Hey there, fellow developer! Ready to dive into the world of DynamoDB with JavaScript? You're in for a treat. We'll be using the @aws-sdk/client-dynamodb
package to make our lives easier. Let's get started!
Before we jump in, make sure you've got:
First things first, let's get our project off the ground:
mkdir dynamodb-integration && cd dynamodb-integration npm init -y npm install @aws-sdk/client-dynamodb
Now, let's set up our DynamoDB client:
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb"); const client = new DynamoDBClient({ region: "us-west-2" });
Easy peasy, right? Make sure to replace "us-west-2" with your preferred region.
Let's create a table to play with:
const { CreateTableCommand } = require("@aws-sdk/client-dynamodb"); const params = { TableName: "Users", KeySchema: [{ AttributeName: "id", KeyType: "HASH" }], AttributeDefinitions: [{ AttributeName: "id", AttributeType: "S" }], ProvisionedThroughput: { ReadCapacityUnits: 5, WriteCapacityUnits: 5 } }; const createTable = async () => { try { const data = await client.send(new CreateTableCommand(params)); console.log("Table created successfully:", data); } catch (err) { console.error("Error creating table:", err); } }; createTable();
Now, let's add some data:
const { PutItemCommand } = require("@aws-sdk/client-dynamodb"); const putItem = async () => { const params = { TableName: "Users", Item: { id: { S: "1" }, name: { S: "John Doe" }, email: { S: "[email protected]" } } }; try { const data = await client.send(new PutItemCommand(params)); console.log("Item inserted successfully:", data); } catch (err) { console.error("Error inserting item:", err); } }; putItem();
Let's fetch that item we just created:
const { GetItemCommand } = require("@aws-sdk/client-dynamodb"); const getItem = async () => { const params = { TableName: "Users", Key: { id: { S: "1" } } }; try { const data = await client.send(new GetItemCommand(params)); console.log("Item retrieved successfully:", data.Item); } catch (err) { console.error("Error retrieving item:", err); } }; getItem();
Time for some changes:
const { UpdateItemCommand } = require("@aws-sdk/client-dynamodb"); const updateItem = async () => { const params = { TableName: "Users", Key: { id: { S: "1" } }, UpdateExpression: "SET #n = :name", ExpressionAttributeNames: { "#n": "name" }, ExpressionAttributeValues: { ":name": { S: "Jane Doe" } } }; try { const data = await client.send(new UpdateItemCommand(params)); console.log("Item updated successfully:", data); } catch (err) { console.error("Error updating item:", err); } }; updateItem();
And finally, let's say goodbye to our item:
const { DeleteItemCommand } = require("@aws-sdk/client-dynamodb"); const deleteItem = async () => { const params = { TableName: "Users", Key: { id: { S: "1" } } }; try { const data = await client.send(new DeleteItemCommand(params)); console.log("Item deleted successfully:", data); } catch (err) { console.error("Error deleting item:", err); } }; deleteItem();
Want to find items that match specific criteria? Here's how:
const { QueryCommand } = require("@aws-sdk/client-dynamodb"); const queryItems = async () => { const params = { TableName: "Users", KeyConditionExpression: "id = :id", ExpressionAttributeValues: { ":id": { S: "1" } } }; try { const data = await client.send(new QueryCommand(params)); console.log("Query successful:", data.Items); } catch (err) { console.error("Error querying items:", err); } }; queryItems();
Need to search through the entire table? Scan's got your back:
const { ScanCommand } = require("@aws-sdk/client-dynamodb"); const scanItems = async () => { const params = { TableName: "Users" }; try { const data = await client.send(new ScanCommand(params)); console.log("Scan successful:", data.Items); } catch (err) { console.error("Error scanning items:", err); } }; scanItems();
Always wrap your DynamoDB operations in try-catch blocks. Here's a pro tip: create a wrapper function for common errors:
const handleDynamoDBError = (err) => { if (err.name === "ResourceNotFoundException") { console.error("The requested resource does not exist"); } else if (err.name === "ProvisionedThroughputExceededException") { console.error("Request rate is too high. Reduce throughput"); } else { console.error("Unexpected error:", err); } };
Use this in your catch blocks for cleaner error handling.
For unit testing, Jest is your friend. Here's a quick example:
const { DynamoDBClient, PutItemCommand } = require("@aws-sdk/client-dynamodb"); jest.mock("@aws-sdk/client-dynamodb"); test("putItem should insert an item successfully", async () => { const mockSend = jest.fn().mockResolvedValue({ /* mocked response */ }); DynamoDBClient.prototype.send = mockSend; await putItem(); expect(mockSend).toHaveBeenCalledWith(expect.any(PutItemCommand)); });
For integration testing, use a local DynamoDB instance or create a separate test table in your AWS account.
And there you have it! You've just built a solid DynamoDB integration using JavaScript. Remember, this is just the tip of the iceberg. DynamoDB has a ton of cool features like transactions, global tables, and more. Keep exploring and happy coding!
Want to see all this code in action? Check out the complete example in this GitHub repository.
Now go forth and build amazing things with DynamoDB! 🚀