DynamoDBのドキュメントにあるサンプルテーブル構成とは、これのことです。
書いてみた
ファイル構成は以下のとおりです。
stacks/prerequisite.ts
このあとで新機能のOpenSearch統合を検証するので、各テーブルにpointInTimeRecovery
とstream
が付いています。不要であれば外してください。
テーブルを作成したあと、aws-cdk-lib/triggers
を使って、ドキュメントにある通りの初期データを投入しています。
aws-cdk-lib/triggers
はCDKのデプロイ中にLambdaを実行する機能で、今回のようにDynamoDBの初期データ投入などで使えます。
import { Construct } from "constructs";
import * as cdk from "aws-cdk-lib";
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
import * as lambda from "aws-cdk-lib/aws-lambda";
import { NodejsFunction, OutputFormat } from "aws-cdk-lib/aws-lambda-nodejs";
import * as trigger from "aws-cdk-lib/triggers";
export class PrerequisiteStack extends cdk.Stack {
public readonly productCatalogTable: dynamodb.ITable;
public readonly forumTable: dynamodb.ITable;
public readonly threadTable: dynamodb.ITable;
public readonly replyTable: dynamodb.ITable;
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
/**
* //////////////
* DynamoDB
* @see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AppendixSampleTables.html
*/
const productCatalog = new dynamodb.Table(this, "ProductCatalog", {
tableName: "ProductCatalog",
partitionKey: { name: "Id", type: dynamodb.AttributeType.NUMBER },
pointInTimeRecovery: true,
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
const forum = new dynamodb.Table(this, "Forum", {
tableName: "Forum",
partitionKey: { name: "Name", type: dynamodb.AttributeType.STRING },
pointInTimeRecovery: true,
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
const thread = new dynamodb.Table(this, "Thread", {
tableName: "Thread",
partitionKey: { name: "ForumName", type: dynamodb.AttributeType.STRING },
sortKey: { name: "Subject", type: dynamodb.AttributeType.STRING },
pointInTimeRecovery: true,
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
const reply = new dynamodb.Table(this, "Reply", {
tableName: "Reply",
partitionKey: { name: "Id", type: dynamodb.AttributeType.STRING },
sortKey: { name: "ReplyDateTime", type: dynamodb.AttributeType.STRING },
pointInTimeRecovery: true,
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
reply.addGlobalSecondaryIndex({
indexName: "PostedBy-Message-Index",
partitionKey: { name: "PostedBy", type: dynamodb.AttributeType.STRING },
sortKey: { name: "Message", type: dynamodb.AttributeType.STRING },
});
/**
* //////////////
* Fixtures
* @see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AppendixSampleTables.html
*/
const triggerHandler = new NodejsFunction(this, "TriggerHandler", {
runtime: lambda.Runtime.NODEJS_20_X,
architecture: lambda.Architecture.ARM_64,
bundling: {
target: "node20",
format: OutputFormat.ESM,
},
});
productCatalog.grantWriteData(triggerHandler);
forum.grantWriteData(triggerHandler);
thread.grantWriteData(triggerHandler);
reply.grantWriteData(triggerHandler);
new trigger.Trigger(this, "Trigger", {
handler: triggerHandler,
executeAfter: [productCatalog, forum, thread, reply],
});
this.forumTable = forum;
this.productCatalogTable = productCatalog;
this.threadTable = thread;
this.replyTable = reply;
}
}
stacks/prerequisite.TriggerHandler.ts
ドキュメントとの整合性のため、@aws-sdk/lib-dynamodb
ではなく@aws-sdk/client-dynamodb
を使っています。
アプリケーションを書くときは@aws-sdk/lib-dynamodb
で楽しましょう!
import { DynamoDB } from "@aws-sdk/client-dynamodb";
const dynamodb = new DynamoDB({ region: "ap-northeast-1" });
export const handler = async () => {
await dynamodb.batchWriteItem({
RequestItems: {
// 長いので割愛します。
// こちらを御覧ください。
// https://github.com/yamatatsu/play-zero-ETL-to-OpenSearch-from-DDB/blob/main/src/stacks/prerequisite.TriggerHandler.ts
},
});
};
リポジトリ
ここに置きました。
まとめ
便利かもしれない!