Serverless NestJS with AWS DynamoDB

Carlos Villarroel
JavaScript in Plain English
8 min readJul 24, 2020

--

If we talk about Databases with NestJS you probably already made some connection with MongoDB and mongoose or MySQL and typeorm.

But if we talk about Serverless with AWS I highly recommend to test DynamoDB.

Why DynamoDB?

First because is Serverless too! Then there is a lot more information about it here:

“Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale. It’s a fully managed, multiregion, multimaster, durable database with built-in security, backup and restore, and in-memory caching for internet-scale applications. DynamoDB can handle more than 10 trillion requests per day and can support peaks of more than 20 million requests per second.”

So it’s fast! Really fast, you can find more information on the page that I posted here.

We are going to connect our Serverless NestJS App with our Dynamo DB.

The objective of this article is that you can connect your NestJS Serverless application with DynamoDB, I will leave you the link to the repository where you can see all the code so that you can download and use it, remember that you must configure an AWS account using the command:

aws configure

We are going to create a simple application with 2 endpoints, the first one to create an order with a title and a category and the second one to get a created order by id.

First Steps: NestJS

We need to create the stack with our lovely command and our serverless.yml file.

Image 1: NestJS Structure

So first let’s talk a little about how I organize a NestJS application:

A NestJS application basically works with a module, service and controller logic.

I also use a repository file, the repository files are used with typeorm and entities for MySQL, I also use this with MongoDB and all my projects, It seems to me that it is much more orderly.

I use the .service.ts for the business logic and the repository for every type of connection to a Database or external API, that way is decoupled and I don’t have to change a lot of logic if I change the DB for example.

Image 2: NestJS Logic

So, now that we already have our base files and NestJS application ok, we need to use serverless to deploy our stack.

Go Serverless!

To deploy our stack we are going to use serverless!

First we need to create our serverless.yml file and configure it to deploy our application:

So we need to give a name to our application and most important we need to create our DynamoDB Table.

As you already see on the NestJS Files image, we need to create two folders, one folder for the AWS IAM Roles and the other for the AWS Resources.

Let’s look at the provider section of the yml, we have our environment variables where is our ORDERS_TABLE_NAME and our iamRoleStatements pointing to the file with the IAMRole for the OrdersTable.

Also we have a custom section, on this custom section you can add everything you need, for example the OrdersTable name and arn that we are going to take once we deploy our application.

You can see the CloudFormation documentation here:

With CloudFormation you can retrieve the name and the arn of your DynamoDB table. So you will have a serverless.yml like this:

Image 3: Serverless.yml file

We need to create our OrdersTable.yml file too, here we reference our DynamoDB Table and define the AttributeDefinitions, in this case I’m using as Attribute name the “id” of type “S” that means “string” and also I’m defining this id in the KeySchema as HASH that is like a Primary Key. I highly recommend to read DynamoDB Documentation too.

So you will have a file like this:

Image 4: OrdersTable.yml file

Finally we need to create our OrdersTableIAM.yml, this file will allow us to PutItems, Scan, GetItem, UpdateItems and Query them from the DynamoDB table that is defined on Resource pointing to the custom section of the serverless.yml.

In this case we are going tou use PutItem and GetItem only. The file should look like this:

Image 5: OrdersTableIAM.yml file

Time to Code

So we are finally done with the configurations. Now we need to code our Repository and our Service to use the Controller and expose the endpoints to create an Order and also to Get an Order by Id.

I will share with you my Github repository with the example code, so I’m not going to write about all the details of the code, only about the Controller and the Repository, remember the logic of our application described on the NestJS section of the article.

Order.Module.ts

Here is the order.module.ts, we are basically providing the order.repository.ts and the order.service.ts.

Image 6: order.module.ts file

Order.Controller.ts

Here is the order controller, it is exposed with the order.module.ts that is imported by the app.module.ts.

So here we have 2 endpoints:

/createOrder: this a POST method that basically creates the Order and response a true or false depending on the result.

/getOrderById/:id: this is a GET method that retrieves an order created by it’s Id.

Image 7: order.controller. ts file

Order.Repository.ts

Finally we have the order.repository.ts, here we import the aws-sdk to use the DynamoDB Client, we also import the uuid to create our unique ids on the DynamoDB, I also use nestjs/common for error handling.

Let’s star for the createOrder method, this receives a createOrderDto that is composed by a title and a category, you can call them directly or use the object destructuring.

We define a const variable called newOrder and then we create a instance of the DynamoDB.DocumentClient(), we use a put calling the TableName from our environment defined in the serverless.yml and the Item that is the newOrder variable that we defined before. This is a promise, if everything goes as expected we will have our new Order created in our DynamoDB table.

For the second method getOrderById that receives the order id, we define a let order variable and we call the DynamoDB.DocumentClient() with the get method using again the TableName and passing the id as object to the Key param, this will return the order that we assign to our order variable.

Image 8: order.repository.ts file

We all this done, we are ready to deploy our application with the sls deploy command.

Deploy the Application

We are done with all the code and configurations, so now we can deploy our Serverless NestJS Application.

sls deploy
Image 9: sls deploy execution
Image 10: sls deploy result

Remember, this command will create the CloudFormation, the Lambda Function, the API Gateway and the DynamoDB Table in your AWS environment using the user that you defined with the aws configure command. Once the process is done you will receive the API url for test it.

Test the Application

Time to test our application, first we need Postman, here is the link in case you don’t have it yet:

So in Postman we are going to create a POST method with the url replacing the “{proxy+}” with “order/createOrder”, we pass the title and category to our order and hit the Send button. If everything goes as expected we will see this response:

Image 11: Testing first endpoint with Postman

Eureka! It works! Let’s check our AWS Console.

In the AWS Console, go to services and then to DynamoDB, you will see the Table that we created, if you click on “Elements” you will see the Order that we just created.

Image 12: AWS Console with DynamoDB

So with the order we can test our second endpoint, click on the Order id and you will see the object, copy the id and let’s try!

Image 13: AWS DynamoDB Object

Back in Postman we create a new GET Request with the same endpoint than before, change the “/order/createOrder” for “order/getOrderById/orderId”, replacing the “orderId” with the id that you copied before. Hit Send and voilà!

We receive the Order that we created before.

Image 14: Testing second endpoint with Postman

We have our Serverless NestJS application working with DynamoDB!

Conclusion

DynamoDB is a really powerfull AWS Tool, is really fast and works great with any type of application, one of the cons is that you have to learn how to use it because is a bit different thant MySQL, Postgres, MongoDB and others. I highly encourage you to give it a try.

If you want more information about Serverless and NestJS, please see my other articles about NestJS and Serverless.

--

--