What You'll Be Creating

In these tutorials, I'll show you how to create and interact with a GraphQL database using AWS AppSync and React Native. This app will have real-time and offline functionality, something we get out of the box with AppSync. In this post we'll get started by setting up the back-end with AppSync.



A great thing about AppSync is that it uses GraphQL—an open standard and a powerful new paradigm for the web and mobile back-end. If you want to learn more about GraphQL, how it differs from REST APIs, and how it can make your job as an app developer easier, check out some of our GraphQL content here on Envato Tuts+.

Learn the principles of the GraphQL API, how it compares to REST, and how to design schemas, implement queries, implement mutations, and more. JavaScript

GraphQL is designed to work with data represented by a graph, and it has a powerful query syntax for traversing, retrieving, and mutating data. Learn how to... GraphQL

In these posts, we will be building a travel app called Cities. Have you ever been watching a show on your favorite food channel and seen an awesome food truck, or spoken to a friend that just got back from a trip and was really excited about the Owl Bar she visited? Well fret no more, we will be building an app for you to keep up with all of those cool places you want to visit, as well as the cities where they are located.



This app will demonstrate and implement all of the functionality you will need to build a real-world, full-stack React Native and GraphQL application.

Check out the example project's GitHub repo to see the completed app and to follow along.

About the Technology

AppSync offers an easy way to get up and running with a scalable, real-time GraphQL server without having to create and maintain it all on your own.

Within the AppSync console, we will do everything from creating our GraphQL schema to provisioning our database and resolvers. The console also has Graphiql set up so we can test and query our database without any extra setup.

We will implement this configuration on our client, which will give us a seamless way to interact with our GraphQL endpoint!

AppSync will allow you to use one of three resolver types right out of the box: DynamoDB, Elasticsearch, or AWS Lambda. We will be using DynamoDB in this tutorial.

Getting Started

The first thing we need to do is create a new AppSync application and add our basic Schema.

Our application will need to store two sets of data—a list of cities and a list of locations that we will associate with individual cities within the list—so our schema will have two main data types (City & Location).

To get started with AppSync, go to the AWS Console and choose AWS AppSync within the Services dropdown menu.

Once we are in the in the AppSync dashboard, we need to click the Create API button:

Now, we will have the option to give the application a name (I'm calling mine TravelApp), and choose the type of schema (custom or sample). We will choose the custom schema option, and then click Create.

The next screen will be the dashboard for the new application. We'll see some useful information right away, including the URL for our app as well as the authorization mode. On the left side, you will see a few links: Schema, Queries, DataSources, and Settings.

Have a look around at the options here before you move on to the next step.

Creating a Schema and Provisioning a Data Source

The next thing we will do is create the schema we would like to use for our application. Again, the schema will have a City and Location type to start off.

From the editor, click on the the Schema tab, and create the following basic schema with two types and one query and click Save:

Attach the Schema to a Database



Now that we have a basic schema created, we need to attach this schema to a database!

AppSync makes this extremely easy. Click the Create Resources button at the right of the screen. We will need two database tables: one to hold our cities, and another to hold our locations.

Choose City, accept all of the defaults, and click Create. You'll notice that this will automatically add some useful queries, mutations, and subscriptions to our schema!

Go ahead and do the same for the Location resource. We have now successfully created two database tables that go along with our schema, and also some basic queries, mutations, subscriptions, and resolvers that will map the schema to those tables (we'll explore the resolvers in the next section).

Let's now take a look at what was created. In the left-hand menu, click on Data Sources.

You should now see the two data sources we just created!

Run Some Test Queries

Now that we have new Mutations and Subscriptions created in our Schema, let's add them to our Schema definition.

To do so, scroll to the bottom of the Schema and update the schema definition to the following:

Next, we can test everything out by creating a mutation and then a query. In the Queries tab, create the following mutation:

This will add a record for Seattle to the city table, with an id of 00001.

Then, create a query to retrieve that data:

When you click the orange play button, you can choose to execute the createCity mutation or the getCity query. Run them both and you should see the Seattle city data retrieved and output on the right side of the screen.



If you want to see how this data is represented in the database, you can explore the DynamoDB city table linked from the Data Sources tab.

Resolver Mapping Templates

You may be wondering how the query maps to the database so seamlessly. The answer is resolvers!

If you look at the right-hand side of the AppSync dashboard's Schema tab, you'll see a section titled Data Types. This lists all of the data types within our Schema. To the right of each field, we see a heading labeled Resolver.

Resolvers are basically the interface between the schema and the database that we are currently using. We can use resolvers for everything from basic retrieval of items to complex actions like fine-grained access control.

Resolvers are written in a DSL called Velocity Templating Language (VTL). AppSync will automatically provision basic resolvers upon datasource creation, but they are highly configurable. At this point, we don't really need to change a lot in our resolvers, but let's take a look at three of the main types of resolvers you'll probably need to work with in the real world. These are connected to the following basic operations:

Getting a single item by its id Getting a list of items Putting an item into the database

Getting an Item by Id

In the Data Types tab, next to the schema definitions, find getCity under Query, and click on CityTable.

This should take you to the resolver configuration screen. From this screen, you'll see that there are three main pieces to a resolver:

Data source name Request mapping template Response mapping template

The data source is the table that you would like to interact with.

The request mapping template describes how the database will handle the request.

Here, you can write your own mapping template or choose from a selection of prepopulated templates for basic actions like getting or putting an item, among other things.

Here, you see the template for getting an item.

The response mapping template describes how to handle the response from the database.

In our response template, we are basically just returning the context.result and wrapping it in the $utils.toJson utility function. This is just one of many helper utils that will abstract away some of the VTL boilerplate. See the complete list of utility methods in the official documentation.

As your application becomes more complex, the key to getting proficient at AppSync is getting comfortable with working with these mapping templates. It took me a few hours to wrap my head around how it all worked, but after experimenting with it for a short while I could see how powerful it is.



We don't have space here to get into all the details of resolver mapping templates, but you can check out the Resolver Resolver Mapping Template Reference and Mapping Template Context Reference to learn more about them.

For now, we'll move on and complete our schema.

Finalizing the AppSync Configuration

We have completed our schema, but we have one last step before we can begin interacting with our new GraphQL endpoint from our React Native application!

Because we are going to be storing all of our locations in one table but querying them based on the city we are currently viewing, we will need to create a secondary index to allow us to efficiently query locations with a particular cityId .

To create a secondary index, go to Data Sources and click on the Location Table hyperlink.

This should take you to the DynamoDB table view for the Location Table. Here, click the Indexes tab and create a new index with a partition key of cityId .

You can lower the read and write capacity units to 1 for the purposes of this tutorial.

Next, we need to update our listLocations query to accept this cityId as an argument, so update the query for listLocations to the following:

Now, we need to update our listLocations resolver to use this new cityId index! Remember, we really only want listLocations to return an array of locations for the city that we are looking at, so the listLocations resolver will take the cityId as a parameter and only return locations for that city.

To get this working, let's update the request mapping template for listLocations to be the following:

Conclusion



In this tutorial, we've created the back-end for a React Native app with its own GraphQL endpoint. We also looked at how to create and update resolvers and work with the AppSync schema.

Now that we are finished configuring everything in the console, we can go ahead and create our React Native client! In the next post, I dive into the React Native mobile app and show you how to hook React Native up to AppSync.

In the meantime, check out some of our other posts about React Native app development!

Some images used with credit from Amazon Web Services, Inc.