DynamoDB with AWS SAM - The Ultimate Guide
Written by Rafal Wilinski
Published on May 8th, 2020
Time to 10x your DynamoDB productivity with Dynobase [learn more]
Why DynamoDB with AWS SAM?
AWS Serverless Application Model (SAM) and DynamoDB work together seamlessly. AWS maintains both services, and each of them is "serverless," meaning you don't need to manage the underlying infrastructure. SAM has a list of special resources and property types which enable much faster development. Moreover, SAM integrates perfectly with other AWS services and has best practices built-in, making it easier to develop, deploy, and manage serverless applications.
In this tutorial, I'll show you how to build a simple API powered by SAM that uses DynamoDB as the data layer.
Step 1 - Prerequisites
Make sure you have the following installed:
- Docker
- AWS profile set up
- Node.js, preferably version > 10
- AWS SAM CLI
You should be able to run the following commands without any issues:
Step 2 - Create new AWS SAM project
Use the following command:
It will guide you through a short project setup wizard. Go ahead and choose:
1
- AWS Quick Start Templates1
- nodejs12.x runtime
And type your project name. After that, change the directory to the newly created one, and to make sure everything was set up correctly, use the sam build
command.
Step 3 - The DynamoDB Table - our data store
First, we'll focus on adding the DynamoDB table into our application.
There are two ways to create a DynamoDB Table in SAM. The first one is the classical one, using AWS::DynamoDB::Table resource. This is the more advanced option but requires a more complicated structure. Fortunately, our DynamoDB Table Designer might help you with that.
The second option is to use the simplified form of AWS::Serverless::SimpleTable resource. It supports only a single attribute primary key but is more intuitive:
Paste that into template.yaml
inside the Resources
section.
Step 4 - Business Logic
Similar to the Serverless Framework tutorial, we'll create three functions for our CRUD app:
- Create Book
- Get Books
- Delete Book
Create function
After creating our SAM app, we should have a hello-world
directory in it. Rename it to books
and open the app.js
file. Replace it with the following contents:
We will also need to change the HelloWorldFunction
part in the template.yaml
file to the following one:
It does a series of things:
- Specifies that the source code of our app is located inside the
books
directory - Sets the function handler to the exported
create
function - Associates that function with API Gateway, specifically with the
POST /book
endpoint
But that's not all. We need to give our Lambda function IAM permission to manipulate our DynamoDB table. Luckily, AWS SAM has a set of special policy templates that make this process much faster. All we need to do is to include the following snippet into the Properties
section of our function:
That was for the create
function. We now want to have the ability to list everything that is in the database.
List/get many function
This one is easy. All we need to do is just run a Scan
operation against our table. Paste the create
function below:
Similar to the previous function, we need to add its definition to the template.yaml
file with slight modifications:
We changed the handler from create
to list
, the event name to ListBooks
, and the method has changed to get
instead of post
.
Delete function
And for the last one, paste this code below the previous one:
The logic here is self-explanatory. Lambda is going to remove a record with the key name where it equals the name
in the path parameter. Don't forget about the template part:
Notice the curly braces in Path
. It will extract the part after /books/
into event.pathParameters.name
which is usable in code.
There's one more thing. In each of these functions, we're referring to the variable TableName
, but right now, it is not set. We can fix that by setting it to the actual table name inside Globals:
Step 5 - Deployment
After changing the code, we need to build it again:
After that, there are two ways to test it: locally and by deploying it to the cloud. If you decide to test it locally with sam local invoke
, you might want to use the DynamoDB Local instance.
Go ahead and deploy it to AWS using this command:
It will ask you a series of questions and save the answers inside samconfig.toml
so you won't be asked about them again.
After a while of waiting, it should output the URL of your API endpoint. Use it to fire a request to check if it works correctly. If it does, then congrats! You've just deployed a production-ready, cloud-native API with AWS Serverless Application Model and DynamoDB!
Additional Considerations
When working with DynamoDB, it's important to understand the pricing model, which is based on the provisioned throughput (read and write capacity units) and the amount of data stored. You can also use DynamoDB's on-demand capacity mode, which automatically scales to handle the load. Additionally, DynamoDB supports various data types, including strings, numbers, binary data, and complex data types like lists and maps, making it versatile for different use cases.
Another key feature of DynamoDB is its support for secondary indexes, which allow you to query the data in different ways without duplicating the data. There are two types of secondary indexes: Global Secondary Indexes (GSI) and Local Secondary Indexes (LSI). GSIs can be created at any time and have their own provisioned throughput, while LSIs must be created at the same time as the table and share the table's provisioned throughput.
Finally, DynamoDB integrates well with other AWS services such as AWS Lambda, Amazon API Gateway, and AWS Step Functions, enabling you to build complex serverless applications. For example, you can use DynamoDB Streams to trigger Lambda functions in response to data changes in your table, allowing you to implement real-time processing workflows.