Now that you’ve created and configured a Next.js app and initialized a new Amplify project, you can add a feature. The first feature you will add is an API. The Amplify CLI supports creating and interacting with two types of API categories: REST and GraphQL. The API you will be creating in this step is a GraphQL API using AWS AppSync (a managed GraphQL service) and the database will be Amazon DynamoDB (a NoSQL database). ## Create a GraphQL API and database Add a [GraphQL API](https://docs.aws.amazon.com/appsync/latest/devguide/designing-a-graphql-api.html) to your app and automatically provision a database by running the following command from the root of your application directory: ```bash amplify add api ``` Select the explicit values below to enable **API key** (for public read access) and **Cognito User Pools** (for authenticated access). ```console ? Select from one of the below mentioned services: GraphQL ? Here is the GraphQL API that we will create. Select a setting to edit or continue Continue ? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, description) ⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules ✅ GraphQL schema compiled successfully. Edit your schema at /next-amplified/amplify/backend/api/nextamplified/schema.graphql or place .graphql files in a directory at /next-amplified/amplify/backend/api/nextamplified/schema ✔ Do you want to edit the schema now? (Y/n) · yes Edit the file in your editor: /next-amplified/amplify/backend/api/nextamplified/schema.graphql ✅ Successfully added resource nextamplified locally ✅ Some next steps: "amplify push" will build all your local backend resources and provision it in the cloud "amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud ``` The CLI will open this GraphQL schema in your text editor. Replace the example schema with the `Post` model below. **amplify/backend/api/nextamplified/schema.graphql** ```graphql type Post @model @auth(rules: [{ allow: owner }, { allow: public, operations: [read] }]) { id: ID! title: String! content: String! } ``` The schema generated is for a blog app. You'll notice a directive on the `Post` type of `@model`. This directive is part of the [GraphQL transform](/cli/graphql/data-modeling) library of Amplify. The GraphQL Transform Library provides custom directives you can use in your schema that allow you to do things like define data models, set up authentication and authorization rules, configure serverless functions as resolvers, and more. A type decorated with the `@model` directive will scaffold out the database table for the type (Post table), the schema for CRUD (create, read, update, delete) and list operations, and the GraphQL resolvers needed to make everything work together. ### Deploying the API To deploy this backend, run the `push` command: ```bash amplify push ``` ```console ⠧ Fetching updates to backend environment: dev from the cloud.⠋ Building resource api/ne⠙ Fetching updates to backend environment: dev from the cloud. ✔ Successfully pulled backend environment dev from the cloud. ⠹ Building resource api/nextamplified ⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules Current Environment: dev ┌──────────┬───────────────┬───────────┬───────────────────┐ │ Category │ Resource name │ Operation │ Provider plugin │ ├──────────┼───────────────┼───────────┼───────────────────┤ │ Api │ nextamplified │ Create │ awscloudformation │ └──────────┴───────────────┴───────────┴───────────────────┘ ✔ Are you sure you want to continue? (Y/n) · yes Cognito UserPool configuration Using service: Cognito, provided by: awscloudformation The current configured provider is Amazon Cognito. Do you want to use the default authentication and security configuration? Default configuration Warning: you will not be able to edit these selections. How do you want users to be able to sign in? Username Do you want to configure advanced settings? No, I am done. ✅ Successfully added auth resource nextamplifiedXXXXXXXX locally ✅ Some next steps: "amplify push" will build all your local backend resources and provision it in the cloud "amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud ⚠️ WARNING: owners may reassign ownership for the following model(s) and role(s): Post: [owner]. If this is not intentional, you may want to apply field-level authorization rules to these fields. To read more: https://docs.amplify.aws/cli/graphql/authorization-rules/#per-user--owner-based-data-access. ✅ GraphQL schema compiled successfully. Edit your schema at /next-amplified/amplify/backend/api/nextamplified/schema.graphql or place .graphql files in a directory at /next-amplified/amplify/backend/api/nextamplified/schema ? Do you want to generate code for your newly created GraphQL API Yes ? Choose the code generation language target javascript ? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.js ? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes ? Enter maximum statement depth [increase from default if your schema is deeply nested] 2 ``` Now the API is live and you can start interacting with it! The API you have deployed includes operations for creating, reading, updating, deleting, and listing posts. Next, run the following command to check Amplify's status: ```bash amplify status ``` This will give us the current status of the Amplify project, including the current environment, any categories that have been created, and what state those categories are in. It should look similar to this: ```console Current Environment: dev ┌──────────┬───────────────────────┬───────────┬───────────────────┐ │ Category │ Resource name │ Operation │ Provider plugin │ ├──────────┼───────────────────────┼───────────┼───────────────────┤ │ Auth │ nextamplifiedXXXXXXXX │ No Change │ awscloudformation │ ├──────────┼───────────────────────┼───────────┼───────────────────┤ │ Api │ nextamplified │ No Change │ awscloudformation │ └──────────┴───────────────────────┴───────────┴───────────────────┘ ``` To view the GraphQL API in the AppSync console at any time, run the following command: ```bash amplify console api ``` To view your entire app in the Amplify console at any time, run the following command: ```bash amplify console ``` ### (Optional) Test your API To test this out locally, you can run the `mock` command. Note: Refer to the [instructions to setup mocking](https://docs.amplify.aws/cli/usage/mock/). > If you'd like to go ahead and connect the front end, you can [jump to the next step](#connect-frontend-to-api). ```bash amplify mock api ``` _Note:_ `amplify mock api` requires Java. ```console # If you have not already deployed your API, you will be walked through the following steps for GraphQL code generation ? Choose the code generation language target: javascript (or preferred target) ? Enter the file name pattern of graphql queries, mutations and subscriptions: src/graphql/**/*.js ? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions: Yes ? Enter maximum statement depth [increase from default if your schema is deeply nested] 2 ``` This will open the GraphiQL explorer on a local port. From the test environment you can try out different operations locally, like queries and mutations. In the GraphiQL toolbar, select **Use: User Pool** and try creating a post: ```graphql mutation CreatePost { createPost(input: { title: "Test Post", content: "post content" }) { id owner title updatedAt createdAt content } } ``` Next, update auth to **Use: API Key** and try querying the list of posts: ```graphql query ListPosts { listPosts { items { content createdAt id owner title } } } ``` ## API with Server-Side Rendering (SSR) import nextCallout from "/src/fragments/lib/ssr/js/next-js-callout.mdx"; In this section you will create a way to list and create posts from the Next.js application. To do this, you will fetch & render the latest posts from the server as well as create a new post on the client. Ensure you have the following libraries installed: ```sh npm install aws-amplify @aws-amplify/ui-react ``` Open **pages/\_app.js** and add the following code to import styles from [Amplify UI](https://ui.docs.amplify.aws): ```jsx import '@aws-amplify/ui-react/styles.css'; ``` Open **pages/index.js** and replace it with the following code: ```jsx // pages/index.js import { Authenticator } from '@aws-amplify/ui-react'; import { Amplify, API, Auth, withSSRContext } from 'aws-amplify'; import Head from 'next/head'; import awsExports from '@/aws-exports'; import { createPost } from '@/graphql/mutations'; import { listPosts } from '@/graphql/queries'; import styles from '../styles/Home.module.css'; Amplify.configure({ ...awsExports, ssr: true }); export async function getServerSideProps({ req }) { const SSR = withSSRContext({ req }); try { const response = await SSR.API.graphql({ query: listPosts, authMode: 'API_KEY' }); return { props: { posts: response.data.listPosts.items, }, }; } catch (err) { console.log(err); return { props: {}, }; } } async function handleCreatePost(event) { event.preventDefault(); const form = new FormData(event.target); try { const { data } = await API.graphql({ authMode: 'AMAZON_COGNITO_USER_POOLS', query: createPost, variables: { input: { title: form.get('title'), content: form.get('content') } } }); window.location.href = `/posts/${data.createPost.id}`; } catch ({ errors }) { console.error(...errors); throw new Error(errors[0].message); } } export default function Home({ posts = [] }) { return (
Amplify + Next.js

Amplify + Next.js

{posts.length} posts

{posts.map((post) => (

{post.title}

{post.content}

))}

New Post

Title
Content