Deploy a Web Application on AWS Amplify

GETTING STARTED GUIDE

Module 2: Build the frontend and connect an API

In this module, you will learn to add an API to your Amplify project

Introduction

In this module, you will build the frontend for your web application and connect to an API (application programming interface) using GraphQL API. GraphQL is a query language for APIs and helps you retrieve and update data on your application.

What You Will Learn

  • Create a basic React frontend application
  • Call a GraphQL API from your application
  • Call the API from your application's frontend

 Time to Complete

10 minutes

 Module Prereqs

  • AWS Account with administrator-level access**
  • Recommended browser: The latest version of Chrome or Firefox

[**]Accounts created within the past 24 hours might not yet have access to the services required for this tutorial.

Implementation

Install Amplify libraries

You need to install the Amplify JavaScript library aws-amplify and Amplify UI library for React @aws-amplify/ui-react (contains the React UI components).

Run the following command to install them:

npm install aws-amplify @aws-amplify/ui-react
You now need to create the frontend for your application. Open the src/index.js file and replace its entire content with the following code to initialize your Amplify libraries:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import "@aws-amplify/ui-react/styles.css"; // Ensure React UI libraries are styled correctly
import { Amplify } from 'aws-amplify'
import awsconfig from './aws-exports'
Amplify.configure(awsconfig) // Configures the Amplify libraries with the cloud backend set up via the Amplify CLI

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Add a GraphQL API with Amplify

You are now going to add an API to the application. Amplify uses AWS AppSync and Amazon DynamoDB to power GraphQL APIs. AppSync is a managed GraphQL service that will take care of our API, and Amazon DynamoDB is a NoSQL database that will store the data our API will use.

To add the API, run amplify add api, and choose the following options to the questions (lines begin with > symbol) - during this step:

renbran@50ed3c3831ed amplify-app % amplify add api
? 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 /Users/renbran/amplify-app/amplify/backend/api/amplifyapp/schema.graphql or place .graphql files in a directory at /Users/renbran/amplify-app/amplify/backend/api/amplifyapp/schema
✔ Do you want to edit the schema now? (Y/n) · yes

A GraphQL schema is a representation of an object and its fields. You need to define your GraphQL schema, and Amplify will create the required DynamoDB table, and configure GraphQL to handle the reads, writes, updates and deletes for you.

If you entered Yes to edit the schema now, your default editor should open to the file needed for the next section.

Create a GraphQL Schema

A GraphQL schema is a representation of an object and its fields. You need to define your GraphQL schema, and Amplify will create the required DynamoDB table, and configure GraphQL to handle the reads, writes, updates and deletes for you. Open the amplify/backend/api/amplifyapp/schema.graphql file and replace the contents with the following:

type Note @model @auth(rules: [{ allow: owner }]) {
  id: ID!
  text: String!
}

This schema defines a Note type with id and text as required fields. It also contains a directives that are part of the Amplify's GraphQL transform library:

@model: A type annotated with @model is stored in DynamoDB and has CRUDL (create, read, update, delete, list) operations automatically created for it.

@auth: A type annotated with @auth is protected by a set of authorization rules. Here, we are using owner authorization to make sure only the owner of a Note will be able to access and modify it.

Deploy Application

You are now ready to deploy your Amplify web application by running amplify push. This will upload your application to your AWS account for you, and Amplify will show you the changes being deployed, and ask to confirm the deployment:
✔ Successfully pulled backend environment dev from the cloud.
Current Environment: dev 
┌──────────┬────────────────────┬───────────┬───────────────────┐ 
│ Category │ Resource name      │ Operation │ Provider plugin   │ 
├──────────┼────────────────────┼───────────┼───────────────────┤ 
│ Api      │ amplifyapp         │ Create.   │ awscloudformation │ 
└──────────┴────────────────────┴───────────┴───────────────────┘ 

? Are you sure you want to continue? Yes
At this point you’ll be prompted to also configure an auth provider. This is because you’ve specified the “owner” based authorization rule above in the GraphQL schema.

Accept all the default values to configure auth with a simple username and password combination:
 Do you want to use the default authentication and security configuration? 
 > Default configuration
 How do you want users to be able to sign in?
 > Username
 Do you want to configure advanced settings?
 > No, I am done.

After confirming the auth settings, select the default values to the follow up questions when prompted:

Update Front End to Use API

To use the new API and auth backend you just deployed, update the src/App.js file by replacing the contents with the following code:
import './App.css';
import { createNote, deleteNote} from './graphql/mutations'
import { listNotes } from './graphql/queries'
import { withAuthenticator, Button, Text, Flex, Heading } from "@aws-amplify/ui-react";
import { useCallback, useEffect, useState } from 'react';
import { API } from 'aws-amplify';

function App({ signOut }) {
  const [ notes, setNotes ] = useState([])

  const fetchNotes = useCallback(async () => {
    const result = await API.graphql({
      query: listNotes,
      authMode: 'AMAZON_COGNITO_USER_POOLS'
    })
    setNotes(result.data.listNotes.items)
  }, [setNotes])

  const handleCreateNote = useCallback(async () => {
    await API.graphql({
      query: createNote,
      variables: { input: { text: window.prompt("New note") } },
      authMode: 'AMAZON_COGNITO_USER_POOLS'
    })
    fetchNotes()
  }, [fetchNotes])

  const handleDeleteNote = useCallback(async (id) => {
    await API.graphql({
      query: deleteNote,
      variables: { input: { id: id } },
      authMode: 'AMAZON_COGNITO_USER_POOLS'
    })
    fetchNotes()
  }, [fetchNotes])

  useEffect(() => {
    fetchNotes()
  }, [fetchNotes])

  return (
    <Flex direction={"column"}>
      <Flex justifyContent={'space-between'}>
        <Heading level={1}>My notes</Heading>
        <Button onClick={signOut}>Sign Out</Button>
      </Flex>
      {notes.map(note => <Flex alignItems={'center'}>
        <Text>{note.text}</Text>
        <Button onClick={() => handleDeleteNote(note.id)}>Remove</Button>
      </Flex>)}
      <Button onClick={handleCreateNote}>Add Note</Button>
    </Flex>
  );
}

export default withAuthenticator(App);

You now have a working application. Login with multi-factor authentication and the application can now communicate with the API to save / update / delete notes.

Test your application

Now you can run your app locally to test it:

npm start

This will start a development server on http://localhost:3000 and open the page in your browser. You will be prompted to sign up before you can use the service - this data is stored in your project's Congnito database, and only you have access to it. Once logged in, the app will only display a heading with Notes App, and a Sign In button as you haven't added anything to it yet. Next, you will add an API to the app. You can use ctrl + c to stop the server again.

With just a few CLI commands and lines of code, we have created a working Single-Page Application with login flow. This application is just a skeleton and login will not work yet. Continue adding functionality to your application in the following sections.

Conclusion

In this module, you learned how to create a React frontend application, add an API to it, and deploy the API to your AWS account. In the next module, you will learn how to deploy the front end from a GitHub repository, and set up a CI/CD pipeline to deploy future changes automatically.

Up Next: Automate Deployment

Was this page helpful?