Loading...
Loading...
Provides TypeScript patterns for DynamoDB-Toolbox v2 including schema/table/entity modeling, .build() command workflow, query/scan access patterns, batch and transaction operations, and single-table design with computed keys. Use when implementing type-safe DynamoDB access layers with DynamoDB-Toolbox v2 in TypeScript services or serverless applications.
npx skill4agent add giuseppe-trisciuoglio/developer-kit dynamodb-toolbox-patterns.build()itemstringnumberlistsetmaprecordGetItemPutItemUpdateItemDeleteItem.build().key().required().default().transform().link().build()npm install dynamodb-toolbox @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodbimport { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
import { Table } from 'dynamodb-toolbox/table';
import { Entity } from 'dynamodb-toolbox/entity';
import { item, string, number, list, map } from 'dynamodb-toolbox/schema';
const client = new DynamoDBClient({ region: process.env.AWS_REGION ?? 'eu-west-1' });
const documentClient = DynamoDBDocumentClient.from(client);
export const AppTable = new Table({
name: 'app-single-table',
partitionKey: { name: 'PK', type: 'string' },
sortKey: { name: 'SK', type: 'string' },
indexes: {
byType: { type: 'global', partitionKey: { name: 'GSI1PK', type: 'string' }, sortKey: { name: 'GSI1SK', type: 'string' } }
},
documentClient
});const now = () => new Date().toISOString();
export const UserEntity = new Entity({
name: 'User',
table: AppTable,
schema: item({
tenantId: string().required('always'),
userId: string().required('always'),
email: string().required('always').transform(input => input.toLowerCase()),
role: string().enum('admin', 'member').default('member'),
loginCount: number().default(0),
tags: list(string()).default([]),
profile: map({
displayName: string().optional(),
timezone: string().default('UTC')
}).default({ timezone: 'UTC' })
}),
computeKey: ({ tenantId, userId }) => ({
PK: `TENANT#${tenantId}`,
SK: `USER#${userId}`,
GSI1PK: `TENANT#${tenantId}#TYPE#USER`,
GSI1SK: `EMAIL#${userId}`
})
});.build()import { PutItemCommand } from 'dynamodb-toolbox/entity/actions/put';
import { GetItemCommand } from 'dynamodb-toolbox/entity/actions/get';
import { UpdateItemCommand, $add } from 'dynamodb-toolbox/entity/actions/update';
import { DeleteItemCommand } from 'dynamodb-toolbox/entity/actions/delete';
await UserEntity.build(PutItemCommand)
.item({ tenantId: 't1', userId: 'u1', email: 'A@Example.com' })
.send();
const { Item } = await UserEntity.build(GetItemCommand)
.key({ tenantId: 't1', userId: 'u1' })
.send();
await UserEntity.build(UpdateItemCommand)
.item({ tenantId: 't1', userId: 'u1', loginCount: $add(1) })
.send();
await UserEntity.build(DeleteItemCommand)
.key({ tenantId: 't1', userId: 'u1' })
.send();import { QueryCommand } from 'dynamodb-toolbox/table/actions/query';
import { ScanCommand } from 'dynamodb-toolbox/table/actions/scan';
const byTenant = await AppTable.build(QueryCommand)
.query({
partition: `TENANT#t1`,
range: { beginsWith: 'USER#' }
})
.send();
const byTypeIndex = await AppTable.build(QueryCommand)
.query({
index: 'byType',
partition: 'TENANT#t1#TYPE#USER'
})
.options({ limit: 25 })
.send();
const scanned = await AppTable.build(ScanCommand)
.options({ limit: 100 })
.send();import { BatchWriteCommand } from 'dynamodb-toolbox/table/actions/batchWrite';
import { TransactWriteCommand } from 'dynamodb-toolbox/table/actions/transactWrite';
await AppTable.build(BatchWriteCommand)
.requests(
UserEntity.build(PutItemCommand).item({ tenantId: 't1', userId: 'u2', email: 'u2@example.com' }),
UserEntity.build(PutItemCommand).item({ tenantId: 't1', userId: 'u3', email: 'u3@example.com' })
)
.send();
await AppTable.build(TransactWriteCommand)
.requests(
UserEntity.build(PutItemCommand).item({ tenantId: 't1', userId: 'u4', email: 'u4@example.com' }),
UserEntity.build(UpdateItemCommand).item({ tenantId: 't1', userId: 'u1', loginCount: $add(1) })
)
.send();TENANT#USER#ORDER#computeKey.options({ consistent: true })references/api-dynamodb-toolbox-v2.md