Connecting Lambda to DynamoDB: A Backend Logic Guide
Learn how to securely connect your Lambda functions to DynamoDB. We cover IAM permissions, the AWS SDK for Node.js, and implementing CRUD logic in your code.

Previously in this course, we covered DynamoDB Data Modeling for Developers and mastered CRUD Operations with AWS SDK. Now that you understand how to structure your tables and interact with them via local scripts, it’s time to move that logic into the cloud.
In this lesson, we will integrate your backend logic with DynamoDB by running your code inside an AWS Lambda environment.
Granting Lambda Permission to Access DynamoDB
By default, a Lambda function is isolated. Even if you have the correct code to read or write to a database, the function will fail with an "Access Denied" error because it lacks the necessary Identity and Access Management (IAM) permissions.
To connect your function to DynamoDB, you must attach an IAM policy to the function's Execution Role. This follows the principle of least privilege: you grant the function only the actions it needs (e.g., dynamodb:PutItem or dynamodb:Query).
The Permission Workflow
- Identify the Role: Every Lambda function has an associated IAM role.
- Define the Policy: Create a JSON policy that allows
dynamodb:PutItemanddynamodb:GetItemon your specific table ARN. - Attach: Attach this policy to the function's role.
If you are using the AWS CDK as we have in previous lessons, this is handled automatically via the table.grantReadWriteData(function) method, which abstracts the IAM policy creation for you.
Writing a Function to Save User Input

Now that permissions are handled, let's write the Lambda Integration logic. We will use the AWS SDK v3 for Node.js.
When you trigger a function (e.g., via an HTTP request), the event object contains your user input. We need to extract that data and pass it to the DynamoDB PutCommand.
JAVASCRIPTconst { DynamoDBClient } = require("@aws-sdk/client-dynamodb"); const { DynamoDBDocumentClient, PutCommand } = require("@aws-sdk/lib-dynamodb"); const client = new DynamoDBClient({}); const docClient = DynamoDBDocumentClient.from(client); exports.handler = async (event) => { // 1. Parse input from the trigger event const body = JSON.parse(event.body); const params = { TableName: process.env.TABLE_NAME, Item: { userId: body.id, userName: body.name, timestamp: new Date().toISOString() } }; try { // 2. Perform the save operation await docClient.send(new PutCommand(params)); return { statusCode: 200, body: "Data saved successfully!" }; } catch (error) { console.error(error); return { statusCode: 500, body: "Failed to save data." }; } };
Querying the Database from a Function
Retrieving data is just as straightforward as saving it. Instead of a PutCommand, you use the GetCommand or QueryCommand.
When querying, ensure your partition key matches the criteria exactly. In a serverless Backend Logic flow, you often receive the ID to search for directly from the URL path parameters or a query string.
JAVASCRIPTconst { GetCommand } = require("@aws-sdk/lib-dynamodb"); // Inside your handler const params = { TableName: process.env.TABLE_NAME, Key: { userId: event.pathParameters.id } }; const result = await docClient.send(new GetCommand(params)); return { statusCode: 200, body: JSON.stringify(result.Item) };
Hands-on Exercise
- Prepare your environment: Ensure your Lambda function has an environment variable named
TABLE_NAMEset to your DynamoDB table name. - Write the code: Replace your existing function code with the
PutCommandexample provided above. - Test: Use the Lambda console's "Test" feature to send a JSON payload containing
{"id": "123", "name": "Test User"}. - Verify: Check your DynamoDB table in the console to confirm the record was created.
Common Pitfalls
- Missing Environment Variables: Forgetting to pass the
TABLE_NAMEinto your function's configuration is the #1 cause of "ResourceNotFound" errors. - Timeouts: If your database calls take too long, your function will terminate. Ensure your Lambda timeout is set to at least 5-10 seconds for standard operations.
- Cold Starts: Initializing the
DynamoDBClientoutside of the handler function (as shown in the code samples) is a best practice. It allows the client to be reused across warm invocations, significantly reducing latency.
FAQ
Q: Do I need to manage connection pools like in SQL databases? A: No. DynamoDB is an HTTP-based service. The AWS SDK handles the connection lifecycle for you.
Q: Should I use async/await for database operations?
A: Yes. Since database operations are I/O bound, async/await ensures your function waits for the response before returning a success or failure status.
Q: Why is my function failing even though the code is correct?
A: Check the CloudWatch logs. If you see a 403 Forbidden error, your IAM role is missing the necessary dynamodb permissions.
Recap

You have now successfully bridged compute and storage. You learned how to grant your Lambda execution role the correct permissions, how to structure the AWS SDK to save user data, and how to query that data back. This connection forms the backbone of the Backend Logic for our serverless web app.
Up next: Handling DynamoDB Errors and Retries
Work with me

AI Chatbot & LLM Integration for Your App or Website
Add a smart AI chatbot or LLM feature to your product — trained on your content, integrated into your stack, and shipped by an AI-native engineer.

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.


