Front-End Web & Mobile

New AWS AppSync features and whitelist removal

At AWS re:Invent 2017, we announced AWS AppSync, which is a managed GraphQL service with offline and real-time data capabilities. Based on customer feedback, we’ve added the following new features for building applications with AWS AppSync.

  • Ability to autogenerate a GraphQL schema and resolvers from an existing Amazon DynamoDB table
  • Android support for offline queries and mutations
  • Interface and union support in GraphQL schemas
  • A “local” resolver to perform data transformations or publish actions using subscriptions
  • Ability to access request headers, including custom headers, within a GraphQL resolver
  • Resolver helper functions for common tasks
  • AWS CloudTrail support

For more details on these features please reference the AWS AppSync documentation.

In addition to the above features, whitelist-only access for using the AWS AppSync Preview has been removed. Now anyone with an AWS account can begin trying out GraphQL with AWS AppSync today. You can get started by using the AWS AppSync console.

Autogenerate GraphQL from DynamoDB

For the launch of AWS AppSync, we included the functionality to write a GraphQL schema and provision DynamoDB tables with resolvers automatically. If you have existing DynamoDB tables, or wish to create tables first then “connect” them to a GraphQL API, AWS AppSync now supports this capability without you needing to write a GraphQL schema or resolvers. This means that with a few clicks you can take any DynamoDB table and create a GraphQL endpoint from it, including offline and realtime functionality.

To do this, navigate to the Datasources section of your GraphQL API in the AWS AppSync console, choose New, and add a friendly name. Use a data source type of Amazon DynamoDB, and choose the table you wish to import. Select the toggle at the bottom to “Automatically generate GraphQL” and two editors will be exposed. The top editor is for customizing the type which will hold data from the DynamoDB table and the bottom editor is a read-only view of the GraphQL schema which will be merged. You can change the type name in the top editor as well as any DynamoDB non-key attributes that you wish to be included in the GraphQL type.

You’ll see CRUDL + Query operations translated to GraphQL types, queries, mutations, and subscriptions. The queries and mutations were created in your schema, and account for both primary and sort keys from the DynamoDB table (if the keys are present) as well any Secondary Indices. Resolvers are automatically set up for you. You can later customize them for your needs, if necessary. If you navigate to the Queries tab of the AWS AppSync console, you can run GraphQL queries or mutations against your table.

 

Android support and custom headers

AWS AppSync is a GraphQL-compliant service, and any GraphQL-compliant client can use an endpoint. Because AWS AppSync uses GraphQL over HTTP, you can also pass in custom headers. As of today’s launch, these are available in your resolvers. For example, you can simply send a GraphQL mutation using curl if you provide an API key, as well as an extra header:

curl -XPOST -H "Content-Type:application/graphql" -H "custom:mytest" \
-H "x-api-key:<API_KEY> -d '{"query" : "query { getInfo(){id name }"}' \
https://<ENDPOINT>/graphql

The customheader will be available in your resolver through$context.request.headers.custom

Speaking of GraphQL-compliant clients, at re:Invent, we launched full support for iOS and JavaScript clients. This includes web (React, Vue, and so on) and hybrid (React Native, Ionic) technologies. Today we’re launching an additional SDK that enables customers using the Apollo client for Android to leverage all the authorization features and offline functionality of AWS AppSync. You can get started by including the AWS AppSync dependencies in your build.gradle file and then instantiating the client:

AWSAppSyncClient client = AWSAppSyncClient.builder()
    .context(context)
    .credentialsProvider(getCredentialsProvider(context))
    .region(Constants.APPSYNC_REGION)
    .serverUrl(Constants.APPSYNC_API_URL)
    .build();

Offline storage, including mutations and persistance across application crashes, is fully supported with the SDK. To learn more please see the tutorial documentation.

Local resolvers

Real-time database functionality in AWS AppSync is provided with GraphQL subscriptions. In fact, any data source in AWS AppSync can use subscriptions, and can trigger subscription notifications to clients as a response to a mutation. However, many customers are building post-processing or out-of-band systems that might alter data independently. Yet they still want to trigger a GraphQL subscription notification without actually changing data.

To help customers with this, we’ve introduced a new data source called “None”, which can be attached to a “local resolver”. When you define a field in your GraphQL schema and use this local resolver, the resolver processes the request and response-mapping template logic without leaving AWS AppSync, and returns results to the caller.

The local resolver opens up some interesting use cases. First, you can use the @aws_subscribe() directive on a mutation with this resolver to publish data to clients without actually making changes to a database. For example, a Lambda function could invoke GraphQL mutations to AWS AppSync in response to some event that takes place, such as processing data that’s uploaded to an S3 bucket. Second, you can still use Velocity Template Language (VTL) to perform logic on data that’s passed to the resolver. Because VTL is a logic-full language, this could be for mathematical computations, string operations over lists and maps, or formatting fields of a GraphQL type that are children in a query that returns values from DynamoDB.

Resolver helper functions

We’re also continuing to make writing business logic easier for developers who need to customize resolver mapping templates in the GraphQL engine.

First, we’ve added a comprehensive programming guide to the AWS AppSync documentation. New features like importing existing DynamoDB tables or creating resources from a GraphQL schema reduce the need for editing resolvers. However, use cases like authorization checks, server-side validation and data generation, and input validation require the ability for customers to be able edit the logic. The programming guide aims to give a “cookbook-style” tutorial on using the VTL language with GraphQL so that these use cases become easier.

Secondly, we’ve added a variety of new utilities to make it easier to perform logic, generate data, and validate. There are also utilities for automatically mapping data to and from DynamoDB tables. This should allow you to add or remove fields from user types in a GraphQL schema without even needing to edit a resolver.

  • $utils.isNull(), $utils.isNullOrEmpty() for data validation conditionals
  • $utils.list.copyAndRemoveAll(), $utils.list.copyAndRetainAll() and related key operations for filtering/mapping over Lists
  • $utils.validate() and $utils.matches() to perform conditional checks, provide error messages, and regular expression matching
  • $utils.typeOf(), $utils.isMap(), $utils.isList(), $utils.isString(), $utils.isNumber()

Also there are several new utilities for generating server time stamps. You can auto-insert these into databases for GraphQL operations, as well as for parsing and formatting. Here are a few examples:

  • $utils.time.nowISO8601(), $utils.time.nowEpochSeconds(), and $utils.time.nowEpochMilliSeconds()
  • $util.time.nowFormatted() and $util.time.parseFormattedToEpochMilliSeconds()
  • $util.time.epochMilliSecondsToSeconds() and $util.time.epochMillisecondsToISO8601()

We’ve also introduced a collection of utilities, called $utils.dynamodb to automatically map GraphQL input arguments to DynamoDB attributes. This is helpful when you just want to work in a GraphQL schema and are quickly iterating on types by adding and removing fields. Instead of needing to also add or remove the corresponding attributes inside the mapping template, this helper expands and contracts as appropriate, passing the values to DynamoDB for persistence. Read more about this in the documentation.

Finally, you can also use $utils.dynamodb.toS3Object() when you use Amazon S3 and GraphQL with the AWS AppSync complex object feature. This makes it easy to store content, such as images or video, with GraphQL. This creates an S3 link, which is a persistence JSON structure in DynamoDB with a reference pointer to Amazon S3. The object can be directly uploaded or downloaded. This new helper converts GraphQL queries and mutations by using S3Object types. It stores them with S3 link notation so that other backend systems and languages, like Java, can use POJO methods to manage the same data.

For more information, see the full list of supported utilities and their descriptions.

Get started with AWS AppSync today

Check out the getting started documentation in the AWS AppSync Developer Guide, as well as some of the sample apps online. We’re excited to hear your feedback on these features and see what you’re building with AWS AppSync. If you have any questions, you can connect with us any time on the AWS AppSync forum.