Build a user settings store with AWS AppSync

Amazon Cognito Sync is a service that you can use for syncing application-related user profile data across devices. The client library caches the data locally so that the app can read and write data, regardless of the device connectivity state. The data stored is limited to key-value pairs where the keys and values are both strings.

However, many organizations need to store more flexible data types—such as integers, JSON documents, and images—in a common store. For example, you might want to store binary data like profile pictures, store the preferences in an alternate data source, or do backend searches that enable you to segment users and do A/B testing.

In this article, I’ll create a data store for storing user settings by using AWS AppSync, which provides a similar structure as Amazon Cognito Sync, but has some additional functionality. AWS AppSync is a GraphQL-based managed service with real-time and offline capabilities. A benefit of this type of data store is that it allows you to extend the store for additional data types. We’ll use this data store in future articles (iOS, Android) for storing user details in an offline repository on Android and iOS devices.

Step 1: Decide on the data model

There are three different ways of setting up user settings, and these are modeled using a GraphQL type. First, I can decide on the user settings up front, define a type of these user settings, and then store a single record per user in the data store. In a GraphQL schema, this would look like the following:

This has the advantage that you’ve specified which settings are permissible. I can store or retrieve any individual setting when it’s required. The schema can also handle nested binary objects (using complex objects) and different types (like dates, numbers, and Booleans).

However, GraphQL is a strongly typed system. This means that I don’t have to use all of the fields in a type on a client, but I can’t use additional fields without adding them into the schema within the service first.

This allows me to use the type system of GraphQL with more flexibility on the client. However, it has the disadvantage of only being able to store strings. Most data has to be converted in order to be stored, and binary data is problematic.

The final technique is to serialize the settings and store the settings as a string:

In this case, I can store any serialized data, as long as it fits in the size of a string within the data store after the data is serialized. For Amazon DynamoDB, that’s limited to 400 KB. This technique has even less flexibility than the key-value store—mostly because the data is stored as a large blob with a specific format.

In this article, I’m going to use the first technique, as it provides great flexibility when I need to work with binary objects.

Step 2: Set up Amazon Cognito

There are two authentication techniques for storing user data—IAM and user pools. Amazon Cognito Sync uses an identity pool for authentication (similar to the IAM role), so I’ll do the same. However, the same technique can be used for user pools. The configuration of AWS AppSync is slightly different in that case.

This process sets up a user pool and identity pool for Amazon Cognito. You can also integrate Facebook or Google social providers, or an enterprise identity provider (IdP) like Active Directory using SAML.

If you already have an Amazon Cognito user pool and identity pool, then you can use the existing resources. You can also configure these resources within the Amazon Cognito console.

Step 3: Set up DynamoDB

In this example, I use DynamoDB as my store. You can configure DynamoDB to work with Amazon Cognito easily within AWS Mobile Hub.

Return to your project in Mobile Hub (if you’re following the prior section, choose the blue banner at the top).

Note that the Settings and SettingsInput types are the same. GraphQL allows for the return type to be different than the type that’s accepted for storage. In this example, they are the same type.

The final step in creating the API is to link the queries and mutations (we have one of each) to the data store by using a resolver. We also want the identity of the user to be automatically stored. This is so that the user always retrieves and stores their settings, but can’t see anyone else’s settings:

{ACCOUNTID} is your AWS account ID. It’s the 12-digit number at the top of the screen in the banner. Remove the hyphens.

{APIID} is the AWS AppSync API ID.

Choose Review policy.

Type a suitable name for the policy, and then choose Create policy.

Optional: If you don’t have authenticated users, you can repeat this process for the unauth_MOBILEHUB IAM role to allow users to sync settings. However, the idendityId can change and doesn’t sync across devices because these unauthenticated users are considered device authenticated.

Your API is now fully configured.

Step 6: Integrate into your client

We have additional articles for both iOS and Android integrations. See the appropriate article for your platform: