Back to Blog
Lesson 15 of the AWS: AWS Core Services for Developers course
Cloud NativeJuly 15, 20263 min read

CRUD Operations with AWS SDK: A Node.js DynamoDB Guide

Master DynamoDB CRUD operations with the AWS SDK for Node.js. Learn to import the SDK, insert data, and retrieve records programmatically in your Lambda.

AWS SDKDynamoDBNode.jsCloud NativeServerless
A vibrant orange arrow on a tree indicates direction in the forest.

Previously in this course, we covered DynamoDB Data Modeling for Developers: A NoSQL Guide, where we designed our table schema. Now that the table exists, we need to interact with it programmatically. This lesson adds the "how-to" for executing CRUD (Create, Read, Update, Delete) operations using the AWS SDK for JavaScript (v3).

The AWS SDK for JavaScript (v3)

The AWS SDK for Node.js is a collection of modular packages. Unlike older versions where you imported the entire library, v3 allows you to import only the specific service clients you need—in our case, DynamoDB. This keeps your Lambda deployment packages smaller and your cold starts faster.

To get started, ensure you have the @aws-sdk/client-dynamodb and @aws-sdk/lib-dynamodb packages in your package.json. We use the lib-dynamodb package because it provides the "DocumentClient," which automatically handles the conversion between standard JavaScript objects and the verbose DynamoDB JSON format (e.g., { "S": "value" }).

Inserting Data (Create)

To insert data, we use the PutCommand. The operation is asynchronous, so we must use async/await to ensure our Lambda function waits for the database confirmation before returning a response.

JAVASCRIPT
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, PutCommand } = require("@aws-sdk/lib-dynamodb");

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

async function saveUser(userId, name) {
  const command = new PutCommand({
    TableName: "UsersTable",
    Item: {
      userId: userId,
      userName: name,
      createdAt: new Date().toISOString(),
    },
  });

  try {
    await docClient.send(command);
    console.log("Success: Item inserted");
  } catch (err) {
    console.error("Error: ", err);
  }
}

Retrieving Data (Read)

Retrieving data uses the GetCommand. You must provide the Primary Key (Partition Key) of the record you wish to fetch. If the item doesn't exist, the SDK won't throw an error; instead, it returns an empty Item property in the response.

JAVASCRIPT
const { GetCommand } = require("@aws-sdk/lib-dynamodb");

async function getUser(userId) {
  const command = new GetCommand({
    TableName: "UsersTable",
    Key: {
      userId: userId,
    },
  });

  const response = await docClient.send(command);
  return response.Item; // Returns the object or undefined
}

Hands-on Exercise: Building a Simple Logger

  1. Create a new Node.js file in your project folder.
  2. Initialize the DynamoDBClient and DynamoDBDocumentClient as shown above.
  3. Write a function that accepts an ID and a string, saves it to your table, and then immediately retrieves and logs the result to the console.
  4. Run the script locally (ensure your AWS credentials from Configuring the AWS CLI are set up correctly).

Common Pitfalls

  • Missing IAM Permissions: Even if your code is perfect, the Lambda function will fail if it lacks dynamodb:PutItem or dynamodb:GetItem permissions. We will address this in the next lesson.
  • Forgetting await: If you omit the await keyword before docClient.send(), your Lambda will finish executing before the database operation completes, leading to "silent" failures.
  • Not using DocumentClient: Trying to use the base DynamoDBClient requires manual attribute typing (e.g., AttributeValue: { S: "my-id" }). Always use lib-dynamodb for a cleaner development experience.

FAQ

Q: Do I need to initialize the client inside the Lambda handler? A: No. Initialize the client outside the handler function. This allows the client to be reused across warm execution environments, significantly improving performance.

Q: Is lib-dynamodb slower than the base client? A: The overhead of the conversion is negligible compared to the network latency of the database call itself. The developer productivity gains far outweigh the cost.

Recap

We've moved from static data modeling to dynamic interaction. By using the DynamoDBDocumentClient, we can now easily perform CRUD operations within our Node.js environment. Remember to keep your SDK imports modular and always handle your promises with async/await.

Up next: Connecting Lambda to DynamoDB — we will secure our infrastructure by granting the necessary IAM permissions to our Lambda function.

Similar Posts