Build a Realtime Serverless GraphQL API with Websockets on AWS

Andrew Griffiths
HackerNoon.com
8 min readJul 19, 2018

--

With the release of AWS AppSync we finally have the ability to create realtime serverless apps on AWS. Previously you were forced to spin up EC2 instances in order to create websocket connections as they are not supported by AWS Lambda.

In the tutorial you’ll learn how to build a simple GraphQL API using AWS AppSync. Then you’ll write a client app in vanilla javascript (no frameworks) that receives realtime updates via websockets. Let’s get started!

1. Setup

Go ahead and install the serverless framework cli which we will be using to deploy our AppSync GraphQL API and create a new directory for our project.

2. Create GraphQL Schema

We will define a basic GraphQL schema for our chat application.

A standard GraphQL schema apart from the realtime subscription which uses a special syntax to indicate to AWS AppSync which mutation to subscribe to (@aws_subscribe(mutations: ["message"])), in this case the message mutation.

3. Create Mapping Templates

Now we have our schema defined we need to add resolvers for it. If you’re expecting to need to write a lambda function you’d be wrong! AppSync introduces the concept of mapping templates which translate the client request to one the backing store (DynamoDB, elasticsearch etc) understands and then translates the response back to the client again.

To keep things simple we are creating an API without a database. AppSync offers a special type of resolver called a local resolver which does not persist the request data but instead just relays it on to whatever subscribers exist at the time.

Let’s create a directory to house our mapping templates.

Then let’s create the request template for our message mutation in a file called mapping-templates/Message.request.vtl which will extract the fields from the mutation request.

For the response we just use the standard forwarding template. Create a file called mapping-templates/ForwardResult.response.vtl with the following contents.

Your folder structure should now look like the following:

4. Deploy AppSync GraphQL API with Serverless Framework

Now we need to create a config file for the serverless framework to provision our API. In order to do this we’re going to use the Serverless-AppSync-Plugin.

Install it with npm.

Then create a serverless.yml file with the following contents.

As you can see we set the data source type to NONE in order to use the local resolver as we do not want to persist the chat messages in a database but instead just forward them to other clients listening for updates.

Our serverless.yml config contains a few environment variables that we must supply. Let’s create a .env file that contains our AWS Account ID and dynamically populates the other variables.

Now we’re ready to deploy our API with a single command:

Congratulations! You’ve just deployed a GraphQL API with realtime support.

5. Create GraphQL Queries For Client Application

The next thing we need to do is to create the GraphQL queries that we will be using from our client to query our API.

First let’s create a directory to house our client code.

Then let’s create a directory for our queries.

Create a file at src/graphql/inboxSubscription.js for our subscription query with the following contents:

This is just a simple subscription query which will return from and body message fields.

6. Download API Config from AWS Console

We need to download the config settings for the app so that it can connect to our GraphQL API.

Navigate to AppSync section in the AWS Console. Select your API and download the web config settings.

You will have a file named AppSync.js in your download area. Move this your src directory and rename it to config.js.

The config file you download should look like the following if you have left the default option for securing your API as API_KEY.

7. Isomorphic Vanilla JavaScript Client Code For Subscribing to Realtime API Updates

We are going to create an isomorphic client — one that can be run either in the browser or via node.js in a terminal.

First let’s install the dependencies we’ll need.

Then let’s create an entrypoint for the application.

Your app source code directory should now have the following contents.

Paste the following code into your index.js file:

For this simple demo we have hardcoded the recipient to Bobby but obviously you’d want to make this dynamic for a real application.

8. Node.js Client Application Build Process

At this point we have all the source code written for our websockets client, we just need to implement the build process. Because the source code uses es6 features we need to transpile it using babel.

Install the dev dependencies we’ll need.

Now let’s build our application.

9. Node.js Client Application

Now let’s run our application in node.js.

Navigate to the queries page in your AppSync API in the AWS console and run the following graphQL mutation to trigger some udpates.

You should see the message appear immediately in your terminal.

10. Browser Client Application Build Process

Remember the code we’ve written is isomorphic. That means it’ll run just as well in the browser.

First install the dev dependencies we’ll need.

We’re going to use webpack to run our build process so we need to create a config file for it. Create a file called webpack.config.js at the route of the project with the following contents.

As the webserver will be serving assets from the dist directory we need to add an index.html file that includes the bundle.js file which webpack will generate. Create a file at dist/index.html with the following contents.

10. Browser Client Application

Run the following command which will start webpack-dev-server serving assets from the dist directory.

Then navigate to http://localhost:8080 in your browser and open the dev tools as we’ll be logging the data to the console.

Navigate to the queries page in your AppSync API in the AWS console and run another graphQL mutation to trigger an update.

You should see the updates being logged to your browser’s console.

12. Conclusion

We’ve set up a serverless GraphQL API with node.js and browser clients consuming realtime updates via websockets. Not bad for under 30 minutes work!

Although AppSync is promoted as a managed GraphQL API service, for me its best feature is the ability to serve realtime updates. Previously you would have had to run a server 24/7 to do this. Now you get all the cost savings of serverless and without any of the headaches of managing servers.

Full source code for this serverless websockets example available on github.

If you’re interested in learning more about building realtime serverless applications then check out my upcoming training course Full Stack Serverless GraphQL Apps on AWS AppSync.

Originally published at andrewgriffithsonline.com.

--

--

Andrew Griffiths
HackerNoon.com

Technology consultant helping companies build and scale using serverless technology https://andrewgriffithsonline.com/