A little bit of context
In the past few years I have been experimenting a lot with AWS based technologies and it's been quite the ride.
Recently I stumbled upon this website and it was quite the reading so I decided to give it a try and share my experience.
What is it?
AWS Amplify is a service provided by Amazon Web Services which gives the ability to create end to end solutions for mobile and web platforms leveraging AWS.
It also provides an easy way to configure features called modules such as named authentication, storage, backend API, hosting and deployments.
Next Steps
In this post I am going to build and deploy a React application with GraphQL.
Pre-Requisites
Make sure you have an account with AWS. It's free.
If your company provides you with a DEV account, first make sure you have the service enabled, otherwise, there is no shame in getting your own personal account.
If you decide to sign up, allow a few hours to get all services enabled, otherwise you will be blocked as you make progress.
Now you should be all set.
Install and configure Amplify CLI
npm install -g @aws-amplify/cli
Now in order to configure the installed Amplify with our AWS account issue the below command.
amplify configure
This will prompt a series of questions that we need to answer.
First, it will ask us to log in to our AWS account using the web console.
The next important question is the IAM user that it will create for our Amplify CLI tool.
After specifying a name for the user it will again redirect us to the IAM console where we need to provide necessary permission policies for our user.
Here make sure to add
AdministratorAccess policy to the user. Then go to
Security Credentials tab and create an access key for this user and remember to download and store credential details. Back in the console as next steps, it will ask for this
accessKeyId and
secretAccessKey. Now our configuration for Amplify CLI is done.
Create a React application
For the creation of a new react application issue the following commands.
npx create-react-app amplify-react-sample
cd amplify-react-sample
npm start
If everything went smoothly in localhost:3000 it should show the newly created react application.
The next step is to add
aws-amplify to our react application as a dependency. This package will have the functionality of doing all the configurations on Amplify from our react code.
npm install aws-amplify @aws-amplify/ui-react
Next, let’s initialize an Amplify project for our react application.
amplify init
Again we will be prompted to answer a series of questions.
For the project name, you can give any name you want. For the type of application select javascript and for the framework select react. For other questions, we can leave the default values since we are not going to change the react build and run scripts inside our application.
The following modifications in our project will be done during this step.
- A new folder named amplify will be created at the root level of the project. This stores every configuration related to our backend (AWS resources). (In this article we are going to add authentication and GraphQL API). As we add more amplify features configurations related to those features will be stored inside this folder as Infrastructure As code.
- A file called aws-exports.js will be created in the src directory that holds all the configuration for the services that we will create with Amplify. For now, it only contains region information because we are still not using any Amplify services.
At the same time on AWS a cloud project will be created which we can access through the Amplify console. The console also gives some other additional configuration options as well for our application.
Add Authentication
For authentication, Amplify uses AWS Cognito as the main authentication provider. AWS Cognito provides many features like authentication, user registration, account recovery, and many more. In order to add Cognito to your app, follow the next command:
amplify add auth
Again we will be prompted with questions for our authentication configurations. We will choose the default configuration for security configuration. (if we want we can update this later by running amplify update auth).
For the sign-in option, you can choose either username or email.
And that’s it, now we have our authentication module created for us. But before testing it in our application we need to push this configuration to Amplify. To do that simply issue the following command in the terminal.
amplify push
This command will create the required configurations on Amplify and Cognito on AWS and will also edit our
aws-exports.js file with Cognito auth configurations.
The next step is to use this Cognito authentication in our react application. For that first, we need to import the Amplify module for our application. Edit
index.js file to import Amplify and configure Amplify module using the configurations in
aws-exports.js file.
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
Now we can use the auth module in our application. Go to
app.js and first import the below modules.
import { withAuthenticator, AmplifySignOut } from "@aws-amplify/ui-react";
Next, wrap our App component with
WithAuthenticator. Here
AmplifySignOut is a component provided by amplify-react where it acts as a sign out button.
Now that we have added the Amplify authentication in our react application let’s start the server and test whether it works.
npm start
and go to the browser.
Now it should display a sign-in page when we try to access localhost:3000. If you can see the above page that means our authentication is set correctly. The next step would be to create a user in our Cognito user pool. You can either create a user through the IAM console or by clicking on
Create account.
Now try to login using the user we created. If everything works just fine let’s move to the next task.
Add GraphQL
Amplify supports creating serverless backend APIs using AWS AppSync. AppSync supports both REST and GraphQL API frameworks. For now we are going to use AppSync GraphQL API.
Before adding our backend GraphQL API let’s do some modifications on our react application in order to show data in a table.
In the above code, I am using material-ui for the creation of the table which you can install using
npm install @material-ui/core
The code only displays a table where for now we have defined a set of data inside fetchActors() method. (Make sure to import the Home component in App.js as well)
Now, let’s make this dynamic using GraphQL to retrieve actor information from an API. To add a GraphQL to our application simply issue the following command in the terminal.
amplify add api
For the questions you will be asked to provide select service as GraphQL and for authorization choose
Amazon Cognito User Pool.
Next for the schema template select Single object with fields. This will automatically create a simple GraphQL schema for us. Next when you asked to edit the schema press Y.
This will open our schema.graphql which is created automatically. There we can see the schema with model Todo already created.
type Todo @model {
id: ID!
name: String!
description: String
}
Now let’s modify this schema for our use case where our model will be
Actors.
type Actor @model {
id: ID!
firstName: String!
lastName: String
age: Int
movies: [String]
gender: String
}
The next step is to push this GraphQL api to Amplify where it will be get created on AppSync. Issue below command to push the API.
amplify push
Now we will be prompted more questions. Select the language target to be
Javascript and make file pattern the
default. Later it will ask to generate all GraphQL operations for our schema. Make sure to enter Yes for this as this will auto-generate Query and Mutation for our Actor model.
This will create our GraphQL API on AppSync. Our database will also get automatically created on AWS DynamoDB. Also, it will create a new folder inside the amplify folder named backend. Our Actor schema and other AppSync related configurations can be found inside this folder.
At the end, we will be provided with the GraphQL endpoint which we have configured using Actors schema. Now if we go to the AppSync console we can see the newly created Actors API.
GraphQL client included so we can test all operations.
Now let’s start adding GraphQL API to our React application.
First, we need to import Amplify, API, graphqlOperation modules in our Home component.
import Amplify, { API, graphqlOperation } from 'aws-amplify'
Next, we need to import Query and Mutation we are going to perform in the application. In our case Query is listActors and Mutation is createActor. We can get these Query or Mutation from either AppSync console or in the aws-schema.graphql file inside backend/api folder
import { createActor} from './graphql/mutations'
import { listActors} from './graphql/queries'
Also, make sure to configure imported Amplify using the correct configurations.
import awsExports from "./aws-exports";
Amplify.configure(awsExports);
Below is the function that we are going to use for fetch actors.
const fetchActors = async () => {
try {
const actorData = await API.graphql(graphqlOperation(listActors))
const actors = actorData.data.listActors.items
setActors(actors)
} catch (err) { console.log('Error when invoking graphqlOperation: listActors') }
}
Now the last thing we need to do is calling this fetchActors() function from UseEffect. Replace previously called fetchActors() with this one.
useEffect(() => {
setActors(fetchActors())
}, [])
Now make sure to leverage the GraphQL client to add a few records. Once that's done we can verify in our App.
Next, let’s try to add actors using our react application. For this, we are going to use addActor Mutation which we already imported.
const addActor = async () => {
try {
if (!formState.firstName || !formState.lastName) return
const actor = { ...formState }
setActors([...actors, actor])
setFormState({ firstName: '', lastName: '', age: 0, movies: '' })
await API.graphql(graphqlOperation(createActor, { input: actor }))
} catch (err) {
console.log('Error when invoking graphqlOperation createActor:', err)
}
}
Apart from creating addActor() function we need to have input fields as well. Below is the fully completed code for the Home component.
Now our page will look like this:
Deploy and host on Amplify
Let’s add the hosting module for our application by issuing the following command.
amplify add hosting
One more time we will be prompted with several questions. For the plugin select
Hosting with Amplify Console and for the type select
Manual deployment.
Finally we need to publish this module to Amplify.
amplify publish
After a few minutes, all infrastructure will be get created and we will have an assigned URL.
You can go ahead and check it to make sure everything works as it should be.
As next iteration we could add CI.