Tutorial: Run DynamoDB locally in Docker, and run NodeJS apps against it
Jun 7, 2019 21:56 · 1007 words · 5 minute read
When developing serverless applications, DynamoDB is often the storage option of choice for its json document storage model and bounded response times at scale. This post is for javascript developers who would like to develop with DynamoDB on their local workstations. You do not need an AWS account to run this tutorial.
We walk through installing docker, the AWS command line tools aws-cli, running “DynamoDB Local” with docker, and then invoking operations on it using the AWS javascript SDK for DynamoDB.
Part 1: Install Docker Engine - Community
If you already have docker installed, skip to Part 2.
1. Confirm the release code name of your Ubuntu OS
$ lsb_release -dc
Description: Ubuntu 15.04
Codename: vivid
2.Download the .deb file
From here, https://download.docker.com/linux/ubuntu/dists/ click on the codename of your OS, then /pool/stable/amd64/
Download the latest version.
3.Install it with
$ sudo dpkg -i /path/to/package.deb
You need to run docker commmands with sudo. Later you can add your user to the docker group.
$ sudo docker run hello-world
Part 2: Install the AWS CLI.
You don’t really need this but its useful for debugging. If you already have AWS CLI setup, skip to Part 3
1. Install the cli with
$ pip3 install awscli --upgrade --user
2. Configure it with
$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: json
If you are using aws-cli only to run commands against DynamoDB-Local, you don’t need real credentials, you can copy the example ones from above. Note that you will not be able to perform any other operations against AWS, so its better to use real access keys.
Part 3: Run DynamoDB local
1. Check if docker is working fine.
$ sudo docker run hello-world
should produce
Hello from Docker! This message shows that your installation appears to be working correctly.
2. Run the local DynamoDB in a docker container
docker run -p 8000:8000 amazon/dynamodb-local
should produce
docker run -p 8000:8000 amazon/dynamodb-local Initializing DynamoDB Local with the following configuration: Port: 8000 InMemory: true DbPath: null SharedDb: false shouldDelayTransientStatuses: false CorsParams: *
(Note this is in-memory and for testing, when you shut down the container, your data will go away!)
Leave this running here.
3. Test DynamoDB-Local using the command line
In a second terminal:
$aws dynamodb list-tables –endpoint-url http://localhost:8000
You should see
{ “TableNames”: [] }
Because there are no tables yet.
Part 4: Write a NodeJs program to connect to DynamoDB Local
1. Create a package.json with
$ mkdir myproj
$ cd myproj
copy this to package.json
{
"dependencies": {},
"name": "aws-nodejs-sample",
"description": "Welcome to DynamoDB Local Setup. Problems? Call Clusterdyne (https://clusterdyne.com). They know AWS!",
"version": "1.0.1",
"main": "sample.js",
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "NAME",
"license": "ISC"
}
2. Install AWS-SDK for javascript
npm install aws-sdk
npm install uuid
3. Create this sample code and run it
This creates a table in DynamoDB-Local
// snippet-start:[dynamodb.JavaScript.table.createTable]
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'REGION'});
// set the end point
AWS.config.update({endpoint: 'http://localhost:8000'});
// Create the DynamoDB service object
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
AttributeDefinitions: [
{
AttributeName: 'CUSTOMER_ID',
AttributeType: 'N'
},
{
AttributeName: 'CUSTOMER_NAME',
AttributeType: 'S'
}
],
KeySchema: [
{
AttributeName: 'CUSTOMER_ID',
KeyType: 'HASH'
},
{
AttributeName: 'CUSTOMER_NAME',
KeyType: 'RANGE'
}
],
ProvisionedThroughput: {
ReadCapacityUnits: 1,
WriteCapacityUnits: 1
},
TableName: 'CUSTOMER_LIST',
StreamSpecification: {
StreamEnabled: false
}
};
// Call DynamoDB to create the table
ddb.createTable(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Table Created", data);
}
});
$node hello.js
Confirm the table is created using aws-cli:
$aws dynamodb list-tables –endpoint-url http://localhost:8000
You should see
{ “TableNames”: [‘CUSTOMER_LIST’] }
4. Put/Get/Delete items
1] Put item in a table.(putitem.js)
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
// set the end point
AWS.config.update({endpoint: 'http://localhost:8000'});
// Create the DynamoDB service object
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
TableName: 'USER_LIST',
Item: {
'USER_ID' : {N: '001'},
'USER_NAME' : {S: 'jon'}
}
};
// Call DynamoDB to add the item to the table
ddb.putItem(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data);
}
});
=> node putitem.js
mycomputer@Dell:~/myproj$ node putitem.js
Success {}
2] Get item from table (getitem.js)
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
// set the end point
AWS.config.update({endpoint: 'http://localhost:8000'});
// Create the DynamoDB service object
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
TableName: 'USER_LIST',
Key: {
'USER_ID' : {N: '001'},
'USER_NAME' : {S: 'Jon'}
},
ProjectionExpression: 'USER_ID , USER_NAME'
};
// Call DynamoDB to read the item from the table
ddb.getItem(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.Item);
}
});
=> node getitem.js
mycomputer@Dell:~/myproj$ node getitem.js
Success {"Item":{"USER_ID":{"N":"1"},"USER_NAME":{"S":"jon"}}}
3] delete item from table (deleteitem.js)
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
// set the end point
AWS.config.update({endpoint: 'http://localhost:8000'});
// Create the DynamoDB service object
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
TableName: 'USER_LIST',
Key: {
'USER_ID' : {N: '001'},
'USER_NAME' : {S: 'jon'}
}
};
// Call DynamoDB to delete the item from the table
ddb.deleteItem(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data);
}
});
=> node deleteitem.js
mycomputer@Dell:~/myproj$ node deleteitem.js
Success { ConsumedCapacity: { TableName: 'USER_LIST', CapacityUnits: 1 } }
4] get all items using query.(query.js)
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
// set the end point
AWS.config.update({endpoint: 'http://localhost:8000'});
// Create the DynamoDB service object
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
ExpressionAttributeValues: {
':s': {N: '000'}
},
ProjectionExpression: 'USER_ID, USER_NAME',
FilterExpression: 'USER_ID >= :s',
TableName: 'USER_LIST'
};
ddb.scan(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
//console.log("Success", data.Items);
data.Items.forEach(function(element, index, array) {
console.log(element.USER_ID.N + " (" + element.USER_NAME.S + ")");
});
}
});
=> node query.js
mycomputer@Dell:~/myproj$ node query.js
2 (David)
1 (jon)
5. Have fun with these other DDB samples
https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/javascript/example_code/dynamodb