GraphQL API using Serverless + AWS AppSync + DynamoDB + Lambda resolvers + Cognito. [Part 2]

Facundo Fasciolo
7 min readOct 4, 2019

--

How to reach a successful implementation.

The tutorial is going to be composed by the following parts:

In part 1, we have configured a basic serverless project that runs an offline AppSync server with a graphql query that returns a list of mocked Books entities, using lambda as resolver.
Now in this second part we are going to mount a DynamoDB database that runs offline and locally, then in part 3 I’m going to teach you how to use that database to store and get all of our entities data.

Well… Let’s start putting hands on code!

DynamoDB: local implementation that runs offline

If you check the official serverless-appsync-offline plugin documentation, you will see that it could be configured to get connected to a DynamoDB host, or to create and start a local DynamoDB database.

When I configured the plugin in order to connect to a remote DynamoDB host I didn’t notice any problem. But I did have some problems when I have tried to configure the plugin in order to mount my own local DynamoDB.

So, in this tutorial, we are going to learn how to use an isolated plugin to mount our local DynamoDB database: serverless-dynamodb-local.

First, we should have to add this plugin to serverless.yml file, under “plugins” section.

serverless.yml

Then, we have to install the plugin (as dev dependency) using npm.

$ npm install --save-dev serverless-dynamodb-local

Now that we have the plugin installed and added to serverless framework, we can start configuring our local database.
To do it, add this DynamoDB configuration under “custom” section.

serverless.yml

onnect to a remote DynamoDB host I didn’t notice any problem. But I did have some problems when I have tried to configure the plugin in order to mount my own local DynamoLet’s see what this configuration means:

  • stages: here we set for which stages we are going to mount this DynamoDB database, because we are going to use a local database only on our machine, we only add stage “local” (the one that defines our offline server). We are going to see deploy and other stages in future parts of this tutorial.
  • start: we can define here, some local database configurations:
    - port: port that local database will be listening to.
    - inMemory: we are going to set this option as false, the database that we are going to mount is file based, the advantage of this is that all the info stored will remain there even if we stop our local server, restart our computer and so on.
    - migrate: setting this option to false we are going to migrate manually our database every time we introduce changes, but we are going to have more control about our tables and all the data within them (and avoid unwanted data lost when migrate is runned).
    - dbPath: here we choose the folder where all the database data files are going to be saved, for that we are going to define a custom directory “dynamodb_local_data”. We have to manually create that directory.

As I said, we are going to configure the serverless-appsync-offline so it gets connected to a DynamoDB instance, instead of mounting and using its internal database. In this case, we are going to tell the AppSync plugin to get connected to our local DynamoDB instance:

serverless.yml

This configuration is pretty straightforward, in appsync-offline configuration, we are adding a parameter that tells to AppSync local server to get connected to a database placed at localhost:8000, the region of our local database should be named “localhost”.

After that, let’s create the directory where all the local database data files are going to be stored.

$ mkdir dynamodb_local_data

With this, we have configured the basics about our local database. Now, we are going to continue defining the tables we need (by the moment we are needing only one table to store Books).

Like other settings that we configured on part 1, we are going to move this tables definitions to an external configuration file, and then include that file path in serverless.yml.
The filename is going to be “resources/dynamo-tables.yml”.

So, add this external configuration file under “resources” section.

serverless.yml

Then we are going to define how we need Books table to be (or at least, which minimun definions we need to specify). Remember that DynamoDB is a non-relational database, so it is not required to define every table element. We will only define necessary attributes that are going to be use as indexes.
For the moment, our Book entity has only two attributes: “id” and “title” (we will add more attributes to it later in the tutorial). In this case we will define “id” as primary key. By the moment we will only have this index on “id”, so that field is the only one to be defined:

resources/dynamodb-tables.yml

This configuration file defines:

  • Type: “AWS::DynamoDB::Table” indicates that the resource is a DynamoDB table.
  • Properties:
    - TableName: defines our books table name, remember that in part 1 it is explained how “${self:custom.defaultPrefix}” works. In this case, at local stage the resulting table name will be “sls-appsync-demo-local-books”.
    - AttributeDefinitions:
    — AttributeName: it is going to be “id” (here we will store book.id value).
    — AttributeType:S” indicates that this attribute type is going to be a String.
    - KeySchema:
    Here we are going to define that our “id” attribute is going to be the primary key.
    — AttributeName:id” -> the attribute we are going to use as key.
    — KeyType: defines the key type. “HASH” indicates that it is a hashKey (a primary key).

Before continue, I recommend you to download a simple application that allow us to have a visual interface to see our local DynamoDB database (or any other remote database if you want). This application is DynamoDB-GUI, and it is available for Ubuntu Linux and MacOS. https://github.com/Arattian/DynamoDb-GUI-Client

If you are using Windows, you should search for some “DynamoDB GUI”, I’m sure there are a bunch of applications for you OS.

Installing the local database

First, let’s install the local DynamoDB engine using the command that gives us serverless-dynamodb-local plugin:

$ serverless dynamodb install

(Tip: if you have any problem with messages that warn you that the version of serverless is older than 1.51 or something like that, you could install serverless as a local dev dependency on the project, besides your global installation, that worked for me in one project where I had that problem).

Once the installation is complete, open a new console tab, and there run the project locally as we did on part 1 of this tutorial:

$ serverless offline start --printOutput --stage local

Then once the project is running, go back to the previous tab and run the command to create the table we have configured:

$ serverless dynamodb migrate

You should see the following message:

Now, open DynamoDB-GUI, and press “Add Database” button, then enter the following parameters, and press “Confirm” button.

DynamoDB-GUI: how to add a connection to our local DynamoDB database.

Now, you should see our new mounted database, and our empty Book table!

Here we can see the table we have defined to store books: “sls-appsync-demo-local-book” table.

So, at this point, we have our local DynamoDB database totally mounted and ready to be used, in the next part we are going to continue creating a mutation that creates and stores a new Book.

You can download the complete implementation code of this “part 2” at this GIT repo commit:
https://github.com/facundofasciolo/sls_appsync_demo/tree/896d25d28c3b59742dbb0c8e0069446907e2ef39

--

--