Building JAMstack Applications with Gatsby and AWS Amplify Framework
When it comes to performance these days, it’s not uncommon to hear the term “JAMstack”. JAMstack stands for JavaScript, APIs, and Markup. The idea being to create static markup with JavaScript that is powered by communicating with APIs.
The reason this stack has become so popular is because it allows websites or apps to be bundled up and served at “the edge” via a CDN. Couple this with what is ideally a performant app that is talking to performant APIs and you get a speedy user experience.
GatsbyJS is a great solution for creating markup with JavaScript, but what about the APIs part and serving your site to the world? Well really, that’s up to you, but in this post I’ll walk through how you can:
- Use AWS Amplify and AWS Cognito to set up authentication
- Use AWS AppSync to create powerful APIs that will let you do all sorts of amazing things with your apps
- How to use AWS Amplify Console to build and deploy your app, making it available to the world using AWS’s global CDN, Amazon CloudFront.
A quick primer on Amplify and AppSync
Amplify lets you create sophisticated serverless backends fast. The CLI includes support for authentication, analytics, functions, REST/GraphQL APIs, and much more. It uses AWS CloudFormation and enables you to add, modify, and share configurations.
Amplify Console is a continuous deployment and hosting service for mobile web applications. The AWS Amplify Console makes it easier for you to rapidly release new features, helps you avoid downtime during application deployment, and handles the complexity of simultaneously updating the frontend and backend of your applications.
AppSync makes it easy to build data driven mobile and web applications by handling securely all the application data management tasks like online and offline data access, data synchronization, and data manipulation across multiple data sources. AWS AppSync uses GraphQL, an API query language designed to build client applications by providing an intuitive and flexible syntax for describing their data requirement.
Gatsby for dynamic apps
Because Gatsby generates static files when possible, it’s often categorized as a static site generation tool, but it’s really so much more than that. Because it’s built on top of React, once your app renders it behaves just like any other React app. That means it’s possible to do things like infinite lists, real-time updates, and create auth walls. It’s not uncommon to add completely client side rendered sections of a site, things like dashboards or admin portals are all possible. This means you can statically generate anything that doesn’t depend on any dynamic content like user information or private data, but still provide an entire app experience.
This post will walk you through creating a blog that allows people to “like” a post. Users not signed in won’t be able to like posts, but will still be able to see them. The blog posts will still be statically generated, allowing for faster delivery and proper SEO support, but users will still be able to dynamically “like” posts. We’ll use AppSync to store the likes and Amplify to set up authentication and create the AppSync API.
Setting up the Gatsby blog
The first thing that needs to be done is making sure you have the gatsby-cli
package installed so that you can create a new Gatsby project.
npm i -g gatsby-cli# ORyarn global add gatsby-cli
Now you can create a project. This example will use the “starter blog” starter.
npx gatsby new blog gatsbyjs/gatsby-starter-blog
You can view all available starters here.
Next you need to set up the client-side app where users can sign in and see what posts they have liked.
To create client-side only routes you first need to update gatsby-node.js
with the following snippet (for more on client-side only routes, head here):
This tells Gatsby that these routes should only be rendered on the client. While you don’t necessarily need this functionality in this example, if your dashboard had many routes this would prevent Gatsby from trying to render those pages, which would error since they don’t exist in the
pages
directory where Gatsby looks for pages to render.
Next you need to add a page for the dashboard. In src/pages
create a new file called dashboard.js
and add the following:
If you run yarn start
and visit http://localhost:8000/dashboard
you should see something that looks like this:
Setting up Amplify
Now that you have your blog set up to support a dashboard, you need to set up Amplify so that you can do things like adding authentication and creating an API. To do this you need to first install the Amplify CLI.
npm i -g @aws-amplify/cli# ORyarn global add @aws-amplify/cli
Once the CLI is installed you need to initialize Amplify in your Gatsby blog project. From the root of the project run amplify init
.
One of two things will happen when you run this command. If you have some AWS user profiles on your computer it will ask if you want to use a profile. (If you have a profile with administrative and programmatic privileges feel free to choose that.) If you don’t have any user profiles created already, or you’re unsure if a current profile will work, then the CLI will actually walk you through how to create one, even going so far as to open the AWS console for you and pre-populating any fields. (You basically just have to click a few buttons, easy peasy.)
For a more in-depth walkthrough of creating a new user profile, check out this informative video from Nader Dabit.
Now that Amplify is properly configured you can start setting up AWS services in your blog!
Setting up authentication
Amplify makes adding services like Cognito for authentication very simple and straight-forward. To set up authentication run the following:
amplify add auth
Once you run the command you will be asked if you want to use the default configuration to set up authentication for your app. This is the recommended auth settings for AWS. (Choose this option if you aren’t familiar with how to configure your own user pools and Cognito configuration.) Next you need to run amplify push
so that the resources can be created and configured in AWS.
After Amplify creates the remote resources for your authentication service, you need to set up Amplify in your blog. To do that you need to:
Install the necessary dependences:
npm i aws-amplify aws-amplify-react# ORyarn add aws-amplify aws-amplify-react
Next you need to import the configuration created by Amplify in src/aws-exports.js
and pass it to the Amplify client. In gatsby-browser.js
add the following:
Then you can update the dashboard with the “withAuthenticator” HOC. This component takes care of the entire sign up flow for you! It’s a really great component, but if you need something more specific you can always create your own sign in flow and use the Auth
module available in aws-amplify
package.
For an example of using the Auth module go here.
Update src/pages/dashboard.js
with the following:
Once you restart Gatsby you should see the following when you visit http://localhost:8000/dashboard
:
The last thing we want to do is add a link to the dashboard from all other pages. We can add that to the Layout
component. Notice in the updated Dashboard
component we are now passing in a isDashboard
prop. We can use this in the Layout
component to determine if we should render the dashboard link or not. Update the return statement in src/components/Layout.js
with the following:
Now we have a link to the dashboard where users can sign in. Go ahead and go through the auth flow to ensure everything works. If you’re curious about what is happening behind the scenes you can view your new user pool here.
Congratulations! Anyone visiting your blog can now sign in! 🎉
While this is exciting, they really can’t do much yet, so now let’s make it possible to like posts!
Creating a GraphQL API via AppSync
Before you can allow users to like posts, you need somewhere to store that information. The next step is to set up an AppSync API so you can use GraphQL to fetch and store data. If you’re unfamiliar…
GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools. — graphql.org
To add an API
service to your blog run amplify add api
. You will be prompted with a few options:
- Use GraphQL
- Provide an API name (I used amplifygatsbyexample)
- Choose “Cognito User Pool” for authentication (this will be automatically connected to the user pool we created in the auth steps).
- Choose no for having an annotated schema
- Choose yes to guided schema creation
- Choose “Single object with fields” for template type
- Choose yes to editing the schema now
Now replace the TODO
type with the following:
If you look at the type, you will notice there are two directives being used on the
PostLike
type. The first one ismodel
, this tells AWS that this is a data type and as such, will create a table for this entity. The second one isauth
, this directive allows us to set up granular authentication or access on our GraphQL API. Here we are specifying that only an owner can access their own PostLikes and the owner is determined by theuserId
value for that entity. Go here for more about GraphQL transforms.
Once that is done, hit enter in the terminal and then run amplify push
again. You will have the option to have the necessary code generated to make queries and mutations, as well as subscriptions. I recommend letting Amplify create the code for you.
You know have an API you can use it to store your likes! If you want to check out your API, you can do so here!
Putting it all together
Now that you have your API set up, it’s time to add support for liking to your Gatsby blog. The first step is to add the ability to like a post.
In order to be able to like a post you first need to add an id
field to the frontmatter
of each blog post. To do so, open the content/blog
folder and add an id
property to each blog post (I used incrementing numbers like 1, 2, 3, etc). It should look something like this:
---title: Hello Worlddate: '2015-05-01T22:12:03.284Z'id: 1---
The next step is to check for a logged in user and if one is found, then check to see if the logged in user has “liked” the post. With this information you can properly set up your mutations for either creating or deleting the like. State is used so that optimistic updates can be made to the UI while you wait for the mutation to process.
Replace src/templates/blog-post.js
with the following:
Here we are using the API
module provided by aws-amplify
, but there is a Connect
component that comes in aws-amplify-react
as well. We’ll make use of that in the next section.
One thing to note is that we don’t have to specify the
userId
property in our mutation input. The reason is because AppSync will use the user that is found on the associated identity making the request. You can learn more about that here.
So now that visitors can like your posts it would be nice for them to see all the posts they have liked. Let’s update src/pages/dashboard.js
with the following:
Here you can see that the blog posts are now being pulled in via Gatsby and we use our AppSync data combined with the blog posts to render a list of liked posts! Go ahead and like a few posts and then visit the dashboard, you should see something like this:
Sweet! Now that all the functionality is set up, the only thing left is to deploy this awesome likable blog!
Deploying to Amplify Console
The first step to getting this blog deployed via Amplify Console is to get it in source control. Create a new repository in your source control provider of choice (I use GitHub, but you can also use GitLab, BitBucket, or AWS Code Commit.)
Once you have your blog pushed to your source control provider, the next step is to connect that repository to Amplify Console. This process is unbelievably simple. Go to the Amplify Console section of AWS console and click the “Deploy” button.
Next choose your source control provider:
Then you can choose the repository and branch you wish to deploy:
Amplify Console will auto-detect that this is a Gatsby project so for the next step about build configuration, just press “Next”!
Lastly, review your settings and hit “Save and Deploy”:
Amplify Console will build the backend infrastructure needed that you have specified in your Amplify config and then it will build and deploy your static site across CloudFront. Amplify Console supports branch deployments, which means you can create an environment for any branch. This makes things like testing, or creating staging environments very easy. It also allows you to set up basic auth for any deployment, making it possible to keep things private and only give access to those who need it.
Your blog is now live and ready for the whole world to enjoy! Congratulations! 🎊 🎉
The code for this example can be found here, and the deployed blog can be found here.
You can play with the code in CodeSandbox here:
If you enjoyed this post I highly recommend checking out some more of the amazing stuff you can do with Amplify and AppSync! You can find a bunch more awesome resources here and here.
Also, if you want to stay up on the latest things I’m writing about or working on, give me a follow on Twitter!