Create a Fast Node.js Serverless Backend Using AWS Lambda and DynamoDB

Create a Fast Node.js Serverless Backend Using AWS Lambda and DynamoDB

ยท

4 min read

In this article, we'll build a simple CRUD JavaScript-based backend with AWS. We'll use Lambda and DynamoDB to show how you can quickly create a secure and robust app backend.

Prerequisites

To follow this tutorial, you need an AWS account. Thankfully, AWS offers a twelve-months free tier plan (isn't that cool? ๐Ÿ˜œ).

Setting up the Lambda function

We'll use the AWS console to create the Lambda function.

  • Choose your preferred region (1), type Lambda in the search field near Services (2), then click on Lambda under Services in the result list (3).

  • On the Lambda dashboard, from the menu list on the left side, click on the Functions menu item (1), then click Create function (2).

  • On the Create function page, select Author from scratch (1), enter the Function name: sample-crud-func (2), choose the Runtime: Node.js 20.x (3), then under Change default execution role, select Create a new role with basic Lambda permissions (4). Finally, click on the Create function button at the bottom.

  • Once the function is ready, open the sample-crud-func function and test it.

    • Select the Test tab (1), then as the Test event action, choose the Create new event option (2). Provide the Event name: test (3), then click the Test button.

Creating the DynamoDB table

The basic Lambda function is now ready. Before we add more logic to it, let's create the DynamoDB table for data storage.

DynamoDB is a fully managed, serverless NoSQL database service provided by AWS for modern applications. There are no upfront costs to launch DynamoDB, and you only pay for what you use.

  • Go to the DynamoDB page, and choose the region. Here, we select us-east-1: N. Virginia (1). In the page menu, select Tables (2), then click on Create table button(3).

  • Provide the Table name (sampleCrudTable), type the Partition key (pk), and then the Sort key (sk). To keep things simple, use the default options and click Create table at the bottom of the page.

Grant Lambda access to the DynamoDB table

  • Let's open the sample-crud-func Lambda function, go to the Configuration (1) tab then in the Execution role section, click on Role name (2) to open the created named role.

  • On the sample-crud-xxx-role-xxx (1) role page, open the Permissions tab (2), then click on the AWSLambdaBasicExecutionRole-xxx policy name (3).

  • On the AWSLambdaBasicExecutionRole-xxx policy page, open the Permissions tab (1), then click on Edit (2).

  • In the Edit policy editor, add the below permission to the permissions list:

              {
                  "Effect": "Allow",
                  "Action": [
                      "dynamodb:PartiQLInsert",
                      "dynamodb:PartiQLUpdate",
                      "dynamodb:PartiQLDelete",
                      "dynamodb:PartiQLSelect"
                  ],
                  "Resource": [
                      "arn:aws:dynamodb:us-east-1:xxx:table/sampleCrudTable"
                  ]
              }
    
  • Note: Remember to replace xxx with your AWS account number.

  • Finally, the Policy editor should look like this:

  • Click on Next, then Save changes to grant the CRUD PartiQL for DynamoDB statements permissions to the Lambda function.

Perform a CRUD operation

  • Head back to the Lambda function we created, open the code tab, and replace the content of the index.mjs file with the following code:
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import {
  DynamoDBDocumentClient,
  ExecuteStatementCommand,
} from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);

const ITEM_PK = "ITEM";

//-------SAVE ITEM FUNCTION-----------
const saveItem = async (tableName, data) => {
  const SK = ITEM_PK + "#" + data?.label; //format PK#label => manage default label sorting

  let result;
  try {
    const command = new ExecuteStatementCommand({
      Statement: `INSERT INTO ${tableName} value {'pk':?,'sk':?,'label':?, 'category':?, 'price':?}`,
      Parameters: [ITEM_PK, SK, data?.label, data?.category, data?.price],
    });

    result = await docClient.send(command);
  } catch (e) {
    console.error(JSON.stringify(e));
    return e;
  }

  return result;
};

export const handler = async (event) => {
  const tableName="sampleCrudTable";

  //Call save Item
  await saveItem(tableName, event)
    .then((res) => {
      console.log(JSON.stringify(res))
    })
    .catch((e) => {
      console.log(JSON.stringify(e.errorMessage));
    });

  const response = {
    statusCode: 200,
    body: JSON.stringify('Hello from Lambda!'),
  };
  return response;
};
  • To test the function, open the Test tab, replace the Event JSON editor (1) content with the following code then click Test (2).
{
  "label": "Paquet de Crayons de couleurs",
  "price": 30,
  "category": {
    "id": 1,
    "label": "Fourniture scolaire"
  }
}

  • Open the DynamoDB table, select Explore items (1) from the left menu, choose the sampleCrudTable table (2), and then click Run (3). You should see the created data (4).

In this article, we guided you through building a simple CRUD backend using AWS Lambda and DynamoDB. You learned how to set up a Lambda function, create a DynamoDB table, grant necessary permissions, and perform CRUD operations using JavaScript.

In the next articles, we'll learn how to secure and protect this backend using API Gateway and Amazon Cognito.

Please subscribe and share. Thanks!

Did you find this article valuable?

Support Wilson KOMLAN by becoming a sponsor. Any amount is appreciated!

ย