What’s new with AWS AppSync

AWS just put out a big release to AWS AppSync – their managed GraphQL data service.  This is the first “major” release since they went public with the service at re:Invent (and you can read all about the release on the AWS Mobile Blog), so what’s new?

You can use it without signing up for the preview

Probably the biggest thing for most people is that you no longer need to sign up for the preview.  Just log in to your AWS console, search for AWS AppSync (or search for GraphQL – that works too!) and start creating a CLI.

It’s available for Android native apps

The easiest way to use the AWS AppSync service from a front end developers perspective is to integrate the Apollo GraphQL client, which is available on a variety of platforms, including JavaScript, React Native, iOS and Android (among others).  However, you can’t just use a HTTP connector.  You have to use the AWS AppSync connector.  At launch, JavaScript, React Native and iOS native were supported.  This release adds  Android native support as well.

It’s easier to generate a schema

Sometimes, especially when learning, we generate a GraphQL schema and then work to create the schema within the database.  AWS AppSync makes that specific case really easy.  That’s not the natural order for the majority of apps though.  In the enterprise, you will be adding a GraphQL API to an existing data source.  While it’s inevitable that you will want to change the schema, AWS AppSync can now generate a GraphQL schema from an Amazon DynamoDB table.  Why inevitable, you ask?  Well, you may not want to expose all the columns of the table to the client applications and you will want to adjust the mutations and queries to match what you are expecting from your client applications.  With the new release of AWS AppSync, you can also “automap” GraphQL fields to DynamoDB without modifying anything other than your schema.  Additionally, you can filter the fields on a per-user or group basis, as required by your security needs.

There are more facilities for subscriptions

One of the awesome features of AWS AppSync is support for real-time subscriptions.  Real-time subscriptions notify all listening clients that there has been a mutation sent to the AWS AppSync service.  While this covers a large portion of the use cases, there are some notable use cases that are not covered with this model.  The major one is what happens when the database is updated in the background?    This situation is fairly common in enterprise database, data like, and big data scenarios.  Since the change is not done via a GraphQL mutation, it isn’t picked up by the subscriptions system and your clients don’t get notified.

The new release introduces the concept of a “local resolver“.  This is a “virtual” mutation to which your client applications can subscribe.  You can use a trigger on your backend database to trigger an AWS Lambda call that then performs the mutation.  Your client applications will then get notified of the changes and download or synchronize the new data.

There are all sorts of use cases for this.  The one I particularly like is post-processing of images.  Let’s say one client uploads an image to an Amazon S3 bucket and you have a Lambda that re-sizes the image before inserting into the database.  At the end of the Lambda code you can call the mutation backed by the local resolver and all your clients will be notified of the new image.

There are more ways to do request and response mapping

Each resolver has a request mapping and a response mapping that are responsible for translating between the client expectations and the backend data source expectations.  These mappings are defined as velocity templates (and the templates have excellent documentation).

Let’s take a look at an example.  I am writing an “enterprise news” type application (more on that in a future blog post).  One of the things that I need is that a person should be able to post a new news item to the database.  I want the mutation to look like this:

type Post {
  postId: ID!
  userId: String!
  content: String!
  creationDate: Int!
}

type Mutation {
  addPost(content: String!): Post!
}

In order to insert the post into the DynamoDB table, I need to be able to add the fields that are not included in the mutation – which is most of them. I can use the following request mapping:

{
  "version": "2017-02-28",
  "operations": "PutItem",
  "key": {
    "postId": { "S" : "${util.autoId()}" },
    "userId": { "S" : "${context.identity.sub}" }
  },
  "attributeValues": {
    "content": { "S" : "${context.arguments.content}" },
    "creationDate": { "N" : ${utils.time.nowEpochMilliSeconds() }
}
}

Here, I’m using two “functions” from the VTL library that AWS AppSync supports – the $util.autoId() function generates a unique ID for your record, and the $util.time.nowEpochMilliSeconds() gives me the current timestamp.

One of the really cool features is that you can integrate custom headers that the client sends to your backend in the request mapping.  This allows, for example, the ability to do authentication based on API key and authorization header, which allows for some unique security and business use cases.

There are also great use cases on the response mapping side.  AWS AppSync does a good job of handling permissions for particular operations.  Sometimes, you need to get even more fine-grained – for instance, by filtering out objects where a field doesn’t match a regular expression based on a field in the identity.  With the new enhancements to VTL, you have many more tools available to handle these use cases.

You can monitor service changes with AWS CloudTrail

Before I would use AWS AppSync for a production workload, there are certain features I would want to have available.   One of these is some sort of operational monitoring.  The Schema and resolver mappings enforce a security perimeter around my database, and I want to ensure that the changes to those are logged for auditing.

AWS Cloudtrail is an operational audit service.  You can log and monitor account activity related to things happening across your AWS infrastructure.   If you are going into production with a GraphQL API based on AWS AppSync, then you will want to understand who is changing the API (and when).  AWS Cloudtrail is the solution for this, and AWS AppSync now supports AWS Cloudtrail.   This brings us one step closer to being able to use AWS AppSync for production workloads.

This joins the existing capabilities of monitoring AWS AppSync with Amazon CloudWatch.  When properly configured, AWS AppSync will send matric to Amazon CloudWatch ever minute, allowing you to monitor client usage, latency and errors.