This library provides a DataLoader layer for efficient fetching from DynamoDB by caching and batching.
get
operation).Define the schema for your tables, specifying each table's name and the attribute names that form the keys used in caching.
import { DynamodbDataLoader, TableSchema } from '@acomagu/dynamodb-dataloader';
const tableSchemas: TableSchema[] = [
{ tableName: "Users", keyAttributeNames: ["userId"] },
{ tableName: "Posts", keyAttributeNames: ["userId", "postId"] }, // PK and SK
]; // Used to enable cache sharing across query, scan, and get operations.
const options = {
dynamodbClient: new DynamoDBClient({ /* AWS SDK configuration options */ }),
getOptions: { /* BatchGet options */ },
};
const dynamodbDataLoader = new DynamodbDataLoader(tableSchemas, options); // All arguments are optional.
Following best practices of DataLoader, a new instance of DynamodbDataLoader should be created per client request.
This example inserts the dataLoader to the Request object in express middleware.
const app = express();
// Middleware to initialize DataLoader and store it in AsyncLocalStorage
app.use((req) => {
req.dataLoader = new DynamodbDataLoader();
});
app.get('/user/:id', async (req, res) => {
const item = await req.dataLoader.getter.load({
TableName: "Users",
Key: { userId: req.params.id },
});
res.send(item);
});
The another way to isolate DataLoader per client request is using AsyncLocalStorage.
const app = express();
const dynamodbDataLoaderStorage = new AsyncLocalStorage();
app.use((req, res, next) => {
dynamodbDataLoaderStorage.run(new DynamodbDataLoader(), next);
});
app.get('/user/:id', async (req, res) => {
const item = await dynamodbDataLoaderStorage.getStore()!.getter.load({
TableName: "Users",
Key: { userId: req.params.id },
});
res.send(item);
});
Fetch data for a specific user ID from the "Users" table using the getter DataLoader:
const getUserRequest = {
TableName: "Users",
Key: { userId: "12345" }
};
const item = await dynamodbDataLoader.getter.load(getUserRequest);
Example of querying posts for a specific user:
const queryPostsRequest = {
TableName: "Posts",
KeyConditionExpression: "userId = :userId",
ExpressionAttributeValues: {
":userId": "12345",
},
};
const items = await dynamodbDataLoader.querier.load(queryPostsRequest);
Scanning for items with a specific filter:
const scanRequest = {
TableName: "Posts",
FilterExpression: "contains(content, :content)",
ExpressionAttributeValues: {
":content": "DynamoDB",
},
};
const items = await dynamodbDataLoader.scanner.load(scanRequest);