How to create AppSync DataLoader

Tomorrow Tech Reviews
3 min readSep 5, 2019

--

I am working on a project with Serverless Architecture using AWS Amplify, AppSync, DynamoDB, Cognito, Lambda, Node.js, React, and React Native.

Let me show how you can fetch data for GraphQL query with a nested list using AWS AppSync, DynamoDB and Lambda functions.

When you work with GraphQL server, you can use DataLoader — utility to reduce requests to the database via batching. But we can’t use it in AppSync. So let’s figure out what batching mechanisms provide AppSync to replace DataLoader.

DynamoDB

We’ll use one DynamoDB table with one-to-many relationships. Countries and cities stored in a single table.

AppSync schema

For example, I’ll use this GraphQL schema.

The query for countries will invoke a Lambda function which will return countries and an empty array of cities. Source of function is here.

This is our response for now.

Lambda function for cities

Now we need a new Lambda function which will fetch cities by an array of countries. Source of function is here. This is what our function will receive as arguments.

[
{
"countryID": "NL",
"countryName": "-",
...
}, {
"countryID": "DE",
"countryName": "-",
...
}, {
"countryID": "IT",
"countryName": "-",
...
}
]

Let’s create a query for cities where countryID is in our array.

Please, keep in mind that DynamoDB operator IN limited to 100 values, separated by commas. More here.

The response should be in the same order as an array of countries.

[
[ // for NL
{
"cityID": "-",
"cityName": "-"
}, {
"cityID": "-",
"cityName": "-"
},
],
[ // for DE
{
"cityID": "-",
"cityName": "-"
}, {
"cityID": "-",
"cityName": "-"
},
],
[ // for IT
{
"cityID": "-",
"cityName": "-"
}, {
"cityID": "-",
"cityName": "-"
},
]
]

Add a resolver

Now we need to use our Lambda function with cities as a resolver for field cities. Let’s move to AppSync and create a new Data Source from the Lambda function.

Let’s found our function.

Now, let’s open our Schema and attach a Resolver to field cities.

  1. Choose our newly created Data Source
  2. Select BatchInvoke and forward arguments
  3. Set Request mapping template to
{
"version" : "2017-02-28",
"operation": "BatchInvoke",
"payload": $util.toJson($ctx.source)
}

Let’s check our query.

Yes, we did it! Now let’s check query with filter. And, yes, it works.

AppSync will invoke a Lambda function to fetch cities only when our query has this field. If not, we’ll fetch only countries from the database.

AWS AppSync is fantastic service. Hope you like it like me.

--

--