Beginner-friendly mobile backend based on AWS AppSync
Are you looking for a way to build a backend for a mobile or web application on AWS? You should check out the newcomer announced by AWS last year: AWS AppSync which provides a GraphQL based API endpoint. AppSync is serverless and very beginner friendly.
What is GraphQL and why do we need it?
GraphQL is a mobile-first approach to build an API and is, therefore, an exciting alternative to RESTful APIs. Facebook is the main contributor to GraphQL. What are the main advantages of GraphQL?
- Minimizing the data transfer: The query language allows the client to ask for exactly the data that is needed, nothing more and nothing less.
- Reducing the number of requests: A request cannot only access a single resource but combine multiple queries.
- Defining a schema: A schema is the core of each GraphQL API. The used type system makes sure your API is well-defined by default.
- Evolving an API: Changing an API without the need of versioned APIs is possible due to the flexible schema and clients defining their expected responses.
- Unifying access: A typical use case for a GraphQL is to unify the access to different backend systems (e.g., legacy applications, microservices, …).
A side note, GraphQL has nothing to do with a graph database. With GraphQL you define your API and might use a SQL, NoSQL, or even more specialized database behind.
Next, we will have a look at GraphQL as a Service on AWS: AppSync.
Sample Application with AWS AppSync
AppSync is very easy to use. All you need to do to create a Serverless API is:
- Create a GraphQL schema.
- Define the data sources: DynamoDB, Lambda, Elasticsearch, generic HTTP, …
- Configure a mapping between your GraphQL schema and the data sources: resolvers.
The repository widdix/aws-cutting-edge-appsync contains a sample application based on AppSync, DynamoDB, and Lambda. The sample application Favorite AWS Architecture lets you vote for the services you would include in your favorite AWS architecture.
The following figure shows the architecture of the Favorite AWS Architecture sample application which is typical for a web application based on AppSync:
- AppSync: the GraphQL API endpoint.
- S3 Bucket: stores and delivers the static assets of the single page application.
- Lambda function: executes your business logic.
- DynamoDB: the NoSQL database.
Defining a Schema
A GraphQL schema consists of the following parts:
- Queries define the read-only operations.
- Mutations specify the write operations.
- Subscriptions configure long-lived connections for receiving real-time data.
A GraphQL schema is comparable to an Open API specification (formerly known as Swagger).
We define the following queries, mutations, and subscriptions for the Favorite AWS Architecture sample application.
type Query { |
On top of that, The GraphQL schema contains the type definition.
The following snippet shows the type definition for our Favorite AWS Architecture sample application.
enum ServiceType { |
AppSync supports the GraphQL scalar types ID
, String
, Int
, Float
, and Boolean
. On top of that, AppSync defines additional scalar types like AWSDate
, AWSEmail
, and AWSURL
. See Scalar types in AWS AppSync
for more details.
Even interfaces and unions are possible with GraphQL. See Interfaces and Unions in GraphQL for more details.
Supported data sources
AppSync supports the following data sources out of the box:
- A DynamoDB table.
- A Elasticsearch domain.
- A Lambda function.
- A RDS Aurora database cluster.
- Any HTTP endpoint.
Our sample application makes use of two data sources: DynamoDB and Lambda. As usual, we are following an infrastructure as code approach based on CloudFormation. The following snippet shows how to define a DynamoDB table, a Lambda function, and the AppSync data sources.
VoteTable: |
Next, we need to connect the data sources to the GraphQL schema. To do so, we need to configure resolvers.
Resolvers
Besides connecting a data source to a query or mutation, a resolver allows you to configure mapping templates for the data sources’ request and response. The template engine Velocity is used by AppSync.
So, first of all, you need to write a request mapping template which transforms the incoming request to a format that the downstream data source can process.
In our sample application Favorite AWS Architecture the following request mapping template is used to query all data from the DynamoDB table storing the voting results from getVotingResults(nextToken: String): VotingResults
.
{ |
The response mapping template is even simpler. It just forwards the result from DynamoDB to the client in JSON format.
$util.toJson($context.result) |
Again, we are using CloudFormation to create the resolver itself.
VotingResultsResolver: |
AppSync allows you to chain resolvers into a so-called pipeline as well. See Pipeline Resolvers for more details.
Subscriptions and offline access
GraphQL is built for mobile applications. Network connectivity is limited on mobile devices. Therefore, GraphQL frameworks like Apollo support caching and offline data access by default.
On top of that, AppSync offers subscriptions - implemented with MQTT over WebSockets - which allows you to notify the client about changes on the API. Necessary to know, with AppSync subscriptions are invoked as a response to a mutation. There is no other way to send a message to the client.
When to use subscriptions instead of polling or manually re-fetching data?
- Initial data set is significant, but only small increments change over time.
- Low-latency updates of the client are essential.
We are using subscriptions to update the voting results for all clients after each change for our Favorite AWS Architecture sample application.
The following snippet shows the subscription voted
defined on the mutation vote
.
type Mutation { |
Deployment Pipeline
It is very convenient to deploy AppSync with CloudFormation. I built my first deployment pipeline for the Favorite AWS Architecture sample application based on CloudFormation, CodeBuild, and CodePipeline within two hours.
Summary
That’s it. AppSync is an easy and powerful way to build Serverless APIs on AWS. My favorite AWS architectures right now:
- AppSync with Lambda and DynamoDB.
- ALB with Fargate and RDS Aurora.
Check out Ten Tips And Tricks for Improving Your GraphQL API with AWS AppSync from re:Invent 2018 for practical tips as well.
This blog post is based on our talk Cutting-Edge Architectures Based on AppSync, Lambda, and Fargate. More than 500 engineers joined us for this talk at the AWS Summit in Berlin. Want us to inspire your developers and architects as well? Invite us to a session at your location.