AWS Database Blog

Build a GraphQL API for Amazon DocumentDB (with MongoDB compatibility) using AWS AppSync

AWS AppSync is a fully managed service that makes it easy to develop GraphQL APIs by handling the heavy lifting of securely connecting to data sources like Amazon DynamoDB, AWS Lambda, and more. Adding caches to improve performance, subscriptions to support real-time updates, and client-side data stores that keep off-line clients in sync are just as easy. After it’s deployed, AWS AppSync automatically scales your GraphQL API execution engine up and down to meet API request volumes.

Amazon DocumentDB (with MongoDB compatibility) is a fast, scalable, highly available, and fully managed document database service that supports MongoDB workloads. You can use the same MongoDB 3.6 and 4.0 or 5.0 application code, drivers, and tools to run, manage, and scale workloads on Amazon DocumentDB without worrying about managing the underlying infrastructure. As a document database, Amazon DocumentDB makes it convenient to store, query, and index JSON data.

In this post, we discuss building a simple GraphQL API using AWS AppSync to retrieve data from Amazon DocumentDB.

Overview of Solution

The post illustrates how to create a GraphQL API using AWS AppSync. We create a GraphQL schema and provision a Lambda function that enables us to connect to Amazon DocumentDB as a data source. We can then run AWS AppSync queries to retrieve data from the sample dataset hosted in Amazon DocumentDB, which contains summary of “Friends” seasons and episodes from the year 1994 to 2005.

The following diagram illustrates the solution architecture.

Prerequisites

To complete the steps in this post, you need the following:

Walkthrough overview

We build this solution using the combination of a CloudFormation stack and a step-by-step walkthrough on the AWS Management Console for the AWS AppSync API:

  1. Launch the CloudFormation stack using the AWS SAM CLI to create the required resources and Amazon DocumentDB cluster.
  2. Build AWS AppSync API, queries and resolver function to interact with Amazon DocumentDB.
  3. Run the queries in the AWS AppSync API to retrieve data from Amazon DocumentDB.

To begin, create a new directory (e.g. blog) and navigate to the directory on your terminal or AWS Cloud9

Clone the GIT repository with the CloudFormation template (template.yaml), Lambda function code (index.js), friendsEpisodes.csv dataset and other required files using below command.

git clone https://github.com/aws-samples/amazon-documentdb-samples.git

You need to build the .zip files for the Lambda layer that holds the database driver and certificate authority file to connect to Amazon DocumentDB and Lambda function. To do this, navigate to the new folder blog/amazon-documentdb-samples/blogs/appsync-docdb created by the preceding command and run the following command:

make

Deploy the CloudFormation Stack

You use AWS SAM CLI to deploy the CloudFormation stack.

  1. Enter the following code:
    sam deploy --capabilities CAPABILITY_NAMED_IAM --guided
  2. Provide the following information in the command line:
    1. The stack name
    2. Which Region to deploy (use ap-south-1,us-east-1,us-west-1,ca-central-1,eu-west-1,eu-central-1 or ap-southeast-1)
    3. The password for accessing the Amazon DocumentDB cluster
    4. Optionally, choose to confirm changes before deploying
    5. Allow the AWS SAM CLI to create an IAM role
    6. Optionally, choose to save the arguments to a configuration file, and choose a configuration file name and a configuration environment
      See the following code

      Configuring SAM deploy
      ======================
      Looking for config file [samconfig.toml] :  Not found
      Setting default arguments for 'sam deploy'
      =========================================
      Stack Name [sam-app]:<your stack name> 
      AWS Region [ap-south-1]:<your regions code) 
      Parameter DocDBPassword:<password> 
      #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
      Confirm changes before deploy [y/N]:<y/N> 
      #SAM needs permission to be able to create roles to connect to the resources in your template
      Allow SAM CLI IAM role creation [Y/n]:<Y/n> 
      Save arguments to configuration file [Y/n]:<Y/n> 
  3. When prompted, deploy this change set
    Deployment takes approximately 10 minutes to complete. You see an output similar to the following

    CloudFormation outputs from deployed stack
    ----------------------------------------------------------------------
    Outputs                                             
    ----------------------------------------------------------------------
    Key      		LambdaFunction              
    Description     	-                           
    Value           arn:aws:lambda:ap-south-1:xxxxxxxxx:function:sam  
                    app-appsync-DocDBFn                                   
    Key             LambdaAppsyncRole                   
    Description     -                                   
    Value           arn:aws:iam::xxxxxxxx:role/sam-app-ResolverAppsyncRole
    Key             ClusterEndpoint                                       
    Description     -                                                     
    Value           sam-app-appsync-demo-cluster.cluster-
                    cr3nkuvgcvie.ap-south-1.docdb.amazonaws.com 
    

    Make note of the preceding resources to use in subsequent steps.

    Along with deploying the required resources, the CloudFormation stack also uploads records from the dataset to the Amazon DocumentDB cluster.

    The following code is the snapshot of a record from the friendsEpisodes.csv dataset preloaded into the Amazon DocumentDB cluster that we for this post. The friendsEpisodes.csv file containing the entire dataset can be found in the directory you created.

    {
    "Year_of_prod" 	: 1994,
    "Season" 	 	: 1,
    "Episode_Title"  : "The One with the Sonogram at the End",
    "Duration" 		: 22,
    "Summary" 	: "Ross finds out his ex-wife is pregnant. 
                       Rachel returns her engagement ring to Barry. Monica becomes 
                       stressed when her and Ross's parents come to visit.",
    "Director" : "James Burrows",
    "Stars" : 8.1,
    "Votes" : 4888
    }

Set up AWS AppSync

Now that the data is loaded into Amazon DocumentDB, you setup the AWS AppSync API. Before you create GraphQL API, let’s review a few concepts that enable you to create a schema, define the data source, and connect with the Lambda resolver.

  • Defining the schema: The schema enables you to create an application where events can be entered. It is comprised of types and can be created or imported. For more information see the GraphQL overview. In this post, the schema definition has the following:
    • Fields representing the friendsEpisodes collection in Amazon DocumentDB
    • The query type to get fields for all episodes from the collection in Amazon DocumentDB, or get a single episode of your choice.
  • Adding a Data source: Our data source is Amazon DocumentDB, which is where our friendsEpisodes collection is located. To interact with Amazon DocumentDB, we use a Lambda function. This Lambda function enables us to connect to Amazon DocumentDB and interact with the collection.
  • Attaching a resolver: A resolver is a function that calls a data source or invokes a trigger to return a value. We use Lambda as our resolver. You attach the Lambda function to the Query fields in the schema. This function determines the query type, connects to Amazon DocumentDB, and retrieves the needed fields.
  1. On the AWS AppSync Console, if this is the first API in the region choose Create API.

  2. Choose Build from scratch.
  3. Choose Start.
  4. For API name, enter appropriate name.
  5. Choose Create.


    You now define the schema, attach the data source and write queries.
  6. Choose Edit Schema.
    On the Schema page, you can design your schema.
  7. Replace the default schema with the following code:
    schema {
      query: Query
    }
    type Post {
      Director: String
      Duration: String
      Episode_Title: String
      Season: String
      Stars: String
      Summary: String
      Votes: String
      Year_of_prod: String!
      _id: ID!
    }
    type Query {
      allEpisodes: [Post]
      getEpisode(Episode_Title: String): Post
    }
  8. Examine all the elements of the schema, and check for any flagged errors.
  9. Choose Save Schema.
    For this post we demonstrate two queries:

    • allEpisodes – Displays all the episodes in the database.
    • getEpisode : Accepts Episode_title as search criteria.
  10. In the navigation pane, choose Data Sources.
  11. Choose Create data source.
  12. For Data source name¸ enter a name (for example, Docdb_Resolver).
  13. For Data source type¸ choose AWS Lambda function.
  14. For Region, choose your Region.
  15. For Function ARN, enter the ARN of the function created by the CloudFormation template.
  16. For Create or use an existing role, select Existing role.
  17. For Select an existing role, choose the ARN of the IAM role created by the CloudFormation template.
  18. Choose Create.
    Now you link the Lambda function to API queries.
  19. In the navigation pane, choose Schema.
  20. In the Resolvers section, navigate to Query and chose Attach next to your queries.
  21. For Data source name choose the data source you defined.
  22. Choose Create.

    This creates an association between the query and the underlying Lambda function to interact with Amazon DocumentDB. The following is the code snippet of the function that interacts with Amazon DocumentDB:

    switch(event.info.fieldName){
            case "getEpisode":
                query = event.arguments;
                result = await collection.findOne(query)
                return result
            case "allEpisodes":
                query = event.arguments;
                result = await collection.find().toArray();
                return result

    Perform this association for both queries.

    Your AWS AppSync Schema page should look like the following screenshot after attaching Lambda resolver function.

Run queries

Now you are ready to run queries.

  1. In the navigation pane choose Queries.
    You can see the two queries available to run: allEpisodes and getEpisode.
    For this post, we demonstrate the allEpisodes query, which displays all the episodes in the database.
  2. In the Explorer pane, choose the allEpisodes query.
  3. Select which variables to query.
    The query preview changes dynamically based on your selection.
  4. Choose the Play icon to run the query.

You can experiment running queries with different fields.

The getEpisode query accepts Episode_title as search criteria and displays results for the particular episode. Queries based on predicates can run optimally using indexes. For more information see working with indexes.

Clean up

To avoid incurring future charges, delete the resources by deleting the CloudFormation stack, the files uploaded to your bucket created by AWS SAM CLI and the AWS AppSync API.

Conclusion

GraphQL helps organizations develop applications faster and enables front-end developers to query multiple databases, microservices, and APIs with a single endpoint. As a fully managed service, AWS AppSync makes it easier to develop GraphQL APIs by removing the heavy lifting of connecting to these multiple databases. Additionally, with Amazon DocumentDB, you can store, query, and index JSON data without having to worry about database management tasks, such as hardware provisioning, patching, setup, configuration, backups, and scaling.

In this post, we showed how to quickly build a simple GraphQL API and use AWS AppSync to retrieve data from Amazon DocumentDB. For more information about building the AWS AppSync GraphQL API, see the AWS AppSync Developer Guide.

If you have any questions or comments about this post, please use the comments section. If you have any feature requests for Amazon DocumentDB, email us at documentdb-feature-request@amazon.com.


About the authors

Anna Kaur is DevOps Consultant for AWS Professional Services based in Toronto. She is passionate about DevOps on AWS and helps customers with their adoption to AWS.

 

 

 

 

Vishram Thatte is a Technical Program Manager with AWS Academy. He has been in the Database and analytics field for over 16 years and has extensive experience with Relational, NoSQL Databases and Data warehousing.