DynamoDB 101
Tags: aws, serverless, node, database
Published: 2022-11-15 17:04:03

This post is written considering you're a fresher to DynamoDB and it only explains the basic concepts that's required to perform CRUD operations. 

The language used in this post in node.js but the underlying concepts are same no matter which language you choose.

## What is DynamoDB?

- DynamoDB is a fully managed No-SQL database as a service provided by AWS.

- DynamoDB is super-fast where you get responses in single digit seconds.

- It's infinitely scaleable on demand 

- The data values in DynamoDB are stored on an SSD which makes it fast, reliable and extremely secure.


## How is the Data Stored?

- The items in DynamoDB are stored in tables.

- Each item in the table contains 2 things a key (which is again of 2 type) and a value which are in the document format.

- A table can store infinite number of items, but each item must not exceed the size of 400kb.

- Your tables have 2 types of keys a primary key which is mandatory (Think of it like the primary key in SQL) and then we have a sort key which is optional (think of it as the foreign key in SQL).

- If you have a primary key alone then each value must be unique but if you're pairing it with a sort key the combination of your primary and sort key must be unique (this helps you filter values efficiently).


## Setup DynamoDB

Please follow the [previous post](https://dev.to/ckmonish2000/lambda-function-with-dynamodb-node-36i6) to setup IAM user with the required.

- Search for DynamoDB in your AWS console and click on create table.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5c3q8imkw8heu6x79sap.png)

- To follow along create a table name Todo with the Partition key called ID and hit create table


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5l3xgk45vfz3b9sns0b2.png)




## Server Setup
Now let's setup our node environment:

- first create a package.json by running `yarn init -y`

- add `"type": "module"` in package.json


![module support npm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8w664466emr4nosr7xs.png)

- now install the dependencies

```
yarn add express dotenv aws-sdk nodemon
```

- now add the scripts section in package.json

```
"scripts": {
    "start": "nodemon index"
  }
```

- create 3 files in your project directory index.js,Database.js and .env.

- In .env add the your IAM user secret, access key and your AWS account region.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/37000uj9tvbodaig84wr.png)

- Now setup your express server 


![express.js server setup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7w7l91lx4kfo92n75a3y.png)

- Go into the Database.js file and let setup our DynamoDB client which allows us to interact with our tables.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5a97t6u1htb6geopreoj.png)

the `aws.config.update` is used to authorize the aws-sdk to access your tables in DynamoDB.

the `const client = new aws.DynamoDB.DocumentClient();` is used to initialize the DynamoDB client.

finally, the constant Table_Names is used to define the DynamoDB table name we just created.

- now create a variable called DB and export it.

```
let DB = {};

export default DB;
```

## CRUD Operations

Before we start coding let's understand few methods provided by the DynamoDB client.

- `put` this method is used to create a new entry in the DB or edit and existing entry.

- `scan` this method is used to all the entries of a given table.

- `get` this method is used to get an element by their partition key or a combination partition and sort key.

- `delete` this method deletes a given element.


All the above methods use a callback in order to convert it into a promise we chain a method called `promise`.

In all the above methods accept an object as an argument where we have to pass in the TableName attributes.

```
const params = {
      TableName: Table_Names,
    }
```

## <u>Add item to table</u>

```
addItem: async (item) => {
    const params = {
      TableName: Table_Names,
      Item: item,
    }
    try {
      return await client.put(params).promise()
    } catch (err) {
      return (err)
    }
  },
```

- In the above code the item parameter can be any JSON object of your choice.



## <u>Get all items from the table</u>

```
getAllItems: async () => {
    const params = {
      TableName: Table_Names,
    }

    try {
      return await client.scan(params).promise()
    } catch (err) {
      return (err)
    }
  }
```

## <u>Get item by id</u>

```
getMemberByID: async (id) => {
    const params = {
      TableName: Table_Names,
      Key: {
        ID: id,
      }
    }
    try {
      return await client.get(params).promise()
    } catch (err) {
      return (err)
    }
  },
```

- In the above function the parameter id is a string which needs to be the ID of the item you want to fetch.

- We use the Key attribute to match the Partition key ID with the parameter id (if you have a sort key that also goes here).


## <u>Delete item by id</u>

```
deleteItem: async (id) => {
    const params = {
      TableName: Table_Names,
      Key: {
        ID: id
      }
    }
    try {
      return await client.delete(params).promise()
    } catch (err) {
      return (err)
    }
  }
```


finally you database.js should look like this:

```
import aws from "aws-sdk";

aws.config.update({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  region: process.env.AWS_REGION
})

const client = new aws.DynamoDB.DocumentClient();
const Table_Names = "Todo"

const DB = {
  addItem: async (item) => {
    const params = {
      TableName: Table_Names,
      Item: item,
    }
    try {
      return await client.put(params).promise()
    } catch (err) {
      return (err)
    }
  },
  getMemberByID: async (id) => {
    const params = {
      TableName: Table_Names,
      Key: {
        ID: id,
      }
    }
    try {
      return await client.get(params).promise()
    } catch (err) {
      return (err)
    }
  },
  deleteItem: async (id) => {
    const params = {
      TableName: Table_Names,
      Key: {
        ID: id
      }
    }
    try {
      return await client.delete(params).promise()
    } catch (err) {
      return (err)
    }
  },
  getAllItems: async () => {
    const params = {
      TableName: Table_Names,
    }

    try {
      return await client.scan(params).promise()
    } catch (err) {
      return (err)
    }
  }
}


export default DB;
```



## Create routes

go to your index.js file and create routes like down below


```
import express from "express";
import env from "dotenv";
import DB from "./Database.js"

env.config();
const app = express();

app.use(express.json())

app.get("/", async (req, res) => {
  const data = await DB.getAllItems();
  res.json(data)
})

app.post("/", async (req, res) => {
  const data = await DB.addItem(req.body)
  res.json(data)
})

app.get("/:id", async (req, res) => {
  const data = await DB.getMemberByID(req.params.id)
  res.json(data)
})

app.delete("/:id", async (req, res) => {
  const data = await DB.deleteItem(req.params.id)
  res.json(data)
})

app.listen(3000, () => {
  console.log("listening on 3000")
})
```

Now you can test the apis using Postman and they should workfine.

I will try to cover more topics related to DynamoDB while building projects with lambda and DynamoDB.

Thanks for time.