Front-End Web & Mobile

Android GraphQL subscriptions and support for complex objects in AWS AppSync

September 14, 2021: Amazon Elasticsearch Service has been renamed to Amazon OpenSearch Service. See details.

AWS AppSync and AWS Amplify have had several releases over the past few months. With AWS AppSync, you can easily apply real-time or offline features to an existing Amazon DynamoDB table. You can also provide complete GraphQL capabilities to your mobile and web applications, including search and discovery features. These features allow you to build transformational features for your business by injecting data into applications in new ways. By using the AWS Amplify features, you can quickly add sign-up and sign-in capabilities to these applications (including social media provider sign-in), and engage your users with robust analytics and push notifications.

In February, AWS AppSync released initial support for GraphQL on Android, which included offline support and synchronization capabilities. Today, we’re releasing GraphQL subscriptions and complex object support for the AWS AppSync Android SDK. These features allow you to build real-time applications that stream data to client applications from data sources such as Amazon DynamoDB, Amazon OpenSearch Service (successor to Amazon Elasticsearch Service), and AWS Lambda. With complex object support, you can use Amazon S3 object storage with GraphQL to synchronize images, video, and other content across devices or between multiple users.

Additionally, we’re releasing a comprehensive sample application that shows how to use complex objects in a React JavaScript application by using AWS Amplify. The sample application shows how to build a private photo-saving application. After a user is signed in, they can use this application to save or retrieve photos in a private S3 bucket. Multiple users can sign in to the application, but the application shows how you can use the fine-grained authorization features of AWS AppSync to restrict access so that users can only see data that they own. The sample also demonstrates other features such as DynamoDB indexed queries with GraphQL, and the ability to use local resolvers to transform data.

Android subscriptions

GraphQL subscriptions are a powerful way for you to enhance your mobile and web applications. They also enable you to choose what data comes down to clients through batched or paginated records with queries, or in real time over a WebSocket channel. The Android SDK automatically merges queries, offline mutations, and real-time updates into a persistent store without you needing to handle object reconciliation.

With this new release, the AWS AppSync tutorial for building an Android client application has been updated with the new subscription and complex object support. The sample GraphQL schema uses the create resources flow, where AWS AppSync automatically creates Amazon DynamoDB tables from a schema, including GraphQL input types and subscription directives.

Android (like iOS) uses code generation to transform GraphQL statements to strongly typed objects. After you’ve added the SDK to your project via Gradle, include a *.graphql file that has any queries, mutations, or subscriptions that’ll be used in your application. For example, for a blog post application where you want to get real-time notifications for new posts, you might use the following subscription:

subscription OnCreatePost {
  onCreatePost {
    id
    author
    title
    content
    url
  }
}

When your Android Studio project builds, you’ll be able to access a type of OnCreatePostSubscription, which was created from the friendly naming nomenclature that you defined in the earlier *.graphql file. For example, you would create a subscription in your application like below:

OnCreatePostSubscription subscription = OnCreatePostSubscription.builder().build();
subscriptionWatcher = ClientFactory.getInstance(this).subscribe(subscription);
subscriptionWatcher.execute(subCallback);

To learn more, see the AWS AppSync Developer Guide.

AWS Amplify with complex objects

The new sample project shows you how to build a GraphQL application for storing and retrieving user photos in a React application. We’ve released this due to popular request because it demonstrates several features:

The client application demonstrates the different levels of flexibility that you have when you’re using AWS Amplify along with AWS AppSync. You can configure your GraphQL API to use Amazon Cognito user pools, but Amazon S3 needs to use AWS IAM credentials for Signature Version 4 signing. With Amplify, you can simply access both of these credentials in the Auth module, and pass them to the AWS AppSync JavaScript client constructor:

const client = new AWSAppSyncClient({
  url: AppSync.graphqlEndpoint,
  region: AppSync.region,
  auth: {
    type: AppSync.authenticationType,
    jwtToken: async () => (await Auth.currentSession()).getAccessToken().getJwtToken(),
  },
  complexObjectsCredentials: () => Auth.currentCredentials(),
});

Your client application can then do GraphQL queries and mutations as appropriate. If the schema is configured with an S3Object type, then an S3Link is created between DynamoDB records and your S3 bucket. The sample also uses a local resolver. When the following listPictures query that lists all records is run, the file field is converted to an appropriate GraphQL response by using an AppSync utility helper for Amazon S3:

query {
  listPictures{
    items {
      id
      name
      visibility
      owner
      createdAt
      file {
        bucket
        region
        key
      }
    }
  }
}

When the React application makes a GraphQL request to AWS AppSync using this query, a JWT token is passed along by AWS Amplify in the Authorization header and is validated by the service. The resolver template then runs a query that compares the username against the owner attribute on each record that the table is indexed by, and returns only the matching records:

{
  "version": "2017-02-28",
  "operation": "Query",
  "query": {
    "expression": "#owner = :owner",
    "expressionNames": {
      "#owner": "owner",
    },
    "expressionValues": {
      ":owner": {"S": "${context.identity.claims.username}"},
    },
  },
  "index": "owner-index",
}

Get started today

We’re excited to see what types of applications you build with these new features. Feel free to leave any feedback on the issue tracker for the sample application. Also, see the getting started documentation in the AWS AppSync Developer Guide, as well as some of the sample apps online. If you have any questions, connect with us on the AWS AppSync forum.