AWS AppSync within Lambda
How to call AppSync queries and mutations within AWS Lambda and Cognito Pools
I’m using AWS AppSync to build Floom. 90% of the time it’s great, but there are still some pretty glaring feature gaps. One of the biggest is not being able to use a private key to access GraphQL operations through AWSAppSyncClient (for example, when doing backend operations with Lambda). It seems like there should be some kind of out-of-the-box admin access that allows you to mutate and query the database without needing to authenticate using AWS Cognito.
If you’re using AppSync, you’ve probably configured your GraphQL API to use AWS Cognito pools (which is the default). Using Cognito pools is incredibly convenient when for controlling access for different users on the client side. It allows you to use the @auth decorator in your schema.graphql to define read (list, get) and write (create, update, delete) access points.
If this is the case, and you want to access the GraphQL operations on your own backend servers (or on AWS Lambda), you are basically limited to two options:
- You can create an admin user in your Cognito Pool and then use that user to get access credentials for the AWSAppSyncClient SDK.
- There is a workaround using AWS IAM roles which is outlined here. This involves creating authenticated and unauthenticated roles, and then creating an Amazon Cognito identity pool and linking the roles you just created to the identity pool. This will also involve changing the authentication mechanism within your client applications. You will no longer be able to use the @auth decorator within schema.graphql, unless you write your own resolvers.
Here, I’ll explain how to move forward with option #1. A bird’s eye view of the process looks like this:
- Set up an admin user in AWS Cognito
- Use the admin’s login credentials to get a session jwtToken from AWS Cognito
- Use this jwtToken to get an instance of AWSAppSyncClient
- Now you can use AppSync GraphQL queries and mutations just like you do on the front end.
Creating an Admin User
I create a user with username admin and add this user to a group that’s also called admin.
Once you’ve done this, make sure that this user will have access to the GraphQL operations you’ll need within your Lambda functions. For example, at Floom, we need to a Transaction once the order has been fulfilled by the seller, so I add an @auth rule which allows users in the admin group complete read/write access to the Transaction model.
Getting A Session Token in Lambda
To access AppSync’s GraphQL operations within Lambda, without needing to switch to AWS_IAM authentication, we’ll need to fetch session tokens using our admin user. We can do this through the CognitoIdentityServiceProvider module of the aws-sdk:
Now that we have Cognito credentials, we can use them to instantiate an instance of the AWSAppSyncClient object, which will allow us to use the AppSync GraphQL queries and mutations.
When you amplify push your schema.graphql changes, Amplify will provide you with a queries.js and a mutations.js with GraphQL operations that look like this:
You can either import this whole file to use in your Lambda function, or simply copy over the ones that you’ll need (remember to update them if you make changes to your schema.graphql.
Now you can use AppSync’s GraphQL operations in a Lambda setting while still using Cognito Authentication (without AWS_IAM roles). When you call mutations, the Amplify GraphQL clients can even subscribe to these mutations using the subscriptions provided in subscriptions.js, like onUpdateTransaction in this case.