You are viewing the preview version of this book
Click here for the full version.

AWS AppSync

AWS AppSync is a managed GraphQL service in the AWS cloud. If you opt to use it, you don't need to think about servers, capacity management, or software updates. Just like with other managed services, you need to configure it correctly and operations is done by AWS. Also, it scales without thresholds, unlike services like OpenSearch or EC2, making it a serverless solution.

Apart from the operational benefits, it also provides a few extra features. It integrates with Cognito, which makes it easy to add user sign-in functionality to the API, and it also provides a few directives for schema-based access control. Also, it allows IAM entities (users, and roles) to securely call the API, which makes it possible to give access to processes, such as Lambda functions or EC2 instances.

type Query {
  # everybody can get themselves
  currentUser: User

  # only admins can query all users
  allUsers: [User]
  @aws_cognito_user_pools(cognito_groups: ["admin"])
}

On top of the GraphQL-defined scalars, AppSync adds a few extra and it also provides built-in validations for them. The AWSDate, the AWSTime, and the AWSDateTime are checked to be in ISO 8601 format (for example, 2022-02-08T10:01:31.474Z), the AWSJSON is a string that is a valid JSON, then the AWSEmail, the AWSPhone, the AWSURL, and the AWSIPAddress all provide some verification to make sure that the value conforms to the expected structure.

AppSync's implementation of resolvers is based on VTL (Velocity Template Language) templates. It needs some getting used to, but this also opens the way to implement simple functionality without Lambda functions. For example, fetching an item from a DynamoDB table is just a few lines of VTL code, instead of a separate Lambda function with all its overhead. And you can always opt out of VTL by writing a Lambda function if you choose to.

VTL resolvers integrate with other AWS services: DynamoDB, RDS, Lambda, OpenSearch, and it support a generic HTTP data source that you can use to integrate with others on the HTTP level.

# sends a GetItem to a DynamoDB table
{
  "version": "2018-05-29",
  "operation": "GetItem",
  "key": {
    "id": {"S": $util.toJson($ctx.args.id)}
  },
  "consistentRead": true
}

One of the main selling point of AppSync is that it supports subscriptions. These are real-time data notifications that pushes data to interested clients, for example, the result of a live sport event can be immediately shown for all visitors. Under the hood, it uses a WebSocket connection, but unlike API Gateway WebSocket APIs, you don't need to handle anything about the individual clients, it is all managed by AppSync. All you need to do is define when it needs to send a notification and it will do the rest, no matter if it's sent to 1 or 1 million clients.

WebSocket-based subscription events

As usual, AppSync fits into the AWS ecosystem: it sends its logs to CloudWatch Logs, metrics to CloudWatch, gets its permissions via IAM Roles, can be deployed with CloudFormation or the CDK, and you can use the Web Application Firewall (WAF) to filter traffic.

AppSync API metrics
AppSync strengths
  • Fully managed service
  • Supports Cognito and IAM for authentication
  • Extra scalars
  • Direct integration with several data sources
  • Real-time data with subscriptions
  • Integrates with the AWS ecosystem

But AppSync has several drawbacks too. A fully managed service is a double-edged sword: if it supports everything you need then it frees you from managing the individual parts. But a missing or broken feature is a source of frustration. And usually the only course of action you can take is to voice your frustration on forums and hope AWS listens.

Also, if you opt in to VTL then you'll find that rapid development using the Management Console is not a pleasant experience. Every save brings you back to the list of resolvers, which makes it harder to change something small and see the result. Not to mention some eventual consistency in the resolver code make the old code run for several seconds after a change.

Just like all AWS services, there are hard limits that you can't change: the maximum schema size, the response size and timeout, as well as the maximum items per resolvers. These are high enough for most applications and if you follow best practices you are unlikely to hit them, but it's good to know that there are immutable values.

Not really a shortcoming of AppSync, but keep in mind that while it supports SQL data sources (RDS, in particular) that needs to use the Data API which is request-based instead of the connection-based native SQL connections. It's a usual serverless pitfall that you can't use the much more optimized direct SQL connections but have to send stateless requests. In practice, that brings database query times from single-digit to low triple-digits milliseconds.

AppSync weaknesses
  • Missing features
  • Resolver development problems
  • Hard limits