Create a DynamoDB table
Hub › AWS › Advanced › Create a DynamoDB table
Goal
After this page you will have a DynamoDB table and a Lambda function that reads and writes items using the AWS SDK.
Prerequisites
- Why DynamoDB
- The intermediate tier
items-apiLambda function deployed.
Create the table
DynamoDB tables need a primary key. For this project you will use a simple pk (partition key) of type string:
bash
# PLACEHOLDER — replace 123456789012 with your account ID; never commit real values.
aws dynamodb create-table \
--table-name items \
--attribute-definitions AttributeName=pk,AttributeType=S \
--key-schema AttributeName=pk,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region us-east-1PAY_PER_REQUEST— you pay per read/write request unit, no capacity planning.HASH— the partition key. DynamoDB distributes items across partitions based on a hash of this key.
Update the Lambda to use DynamoDB
Replace index.mjs with this version that reads from DynamoDB:
javascript
// index.mjs — Lambda (Node.js 20), reads items from DynamoDB
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, ScanCommand, PutCommand } from "@aws-sdk/lib-dynamodb";
const client = new DynamoDBClient({ region: "us-east-1" });
const docClient = DynamoDBDocumentClient.from(client);
const TABLE_NAME = "items";
export const handler = async (event) => {
try {
if (event.requestContext?.http?.method === "POST") {
const body = JSON.parse(event.body);
const item = {
pk: body.id?.toString() || crypto.randomUUID(),
name: body.name || "untitled",
createdAt: new Date().toISOString(),
};
await docClient.send(new PutCommand({ TableName: TABLE_NAME, Item: item }));
return { statusCode: 201, headers: { "Content-Type": "application/json" }, body: JSON.stringify(item) };
}
const result = await docClient.send(new ScanCommand({ TableName: TABLE_NAME }));
return {
statusCode: 200,
headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" },
body: JSON.stringify(result.Items || []),
};
} catch (err) {
return { statusCode: 500, headers: { "Content-Type": "application/json" }, body: JSON.stringify({ error: err.message }) };
}
};The Lambda execution role needs dynamodb:Scan and dynamodb:PutItem on the items table. Attach this inline policy:
bash
# PLACEHOLDER — replace with your account ID and function name.
aws iam put-role-policy \
--role-name lambda-basic-execution \
--policy-name dynamodb-items-access \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["dynamodb:Scan", "dynamodb:PutItem"],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/items"
}]
}'Redeploy the Lambda:
bash
# PLACEHOLDER — use your own function ARN and role ARN.
zip function.zip index.mjs
aws lambda update-function-code --function-name items-api --zip-file fileb://function.zipCheckpoint test
After redeploying, call the API to verify it returns data:
bash
# PLACEHOLDER — replace with your API Gateway invoke URL.
curl https://abcd1234.execute-api.us-east-1.amazonaws.com/itemsExpected: a 200 with an empty array [] (the table is new). Then POST a new item:
bash
# PLACEHOLDER — replace with your invoke URL.
curl -X POST https://abcd1234.execute-api.us-east-1.amazonaws.com/items \
-H "Content-Type: application/json" \
-d '{"id": "1", "name": "Notebook"}'Expected: 201 with the created item. Run the GET again — the item now appears.
Next → Cognito auth