Skip to content

TypeScript DynamoDB

このジェネレーターは、Amazon DynamoDB をバックエンドとする新しい TypeScript DynamoDB プロジェクトを作成します。型安全なエンティティモデリングには ElectroDB を使用します。AWS CDK または Terraform を使用して DynamoDB テーブルをプロビジョニングおよび管理するために必要なアプリケーションコードとインフラストラクチャを生成し、シングルテーブル設計のサポートと DynamoDB Local によるローカル開発機能を備えています。

TypeScript DynamoDB プロジェクトを生成する

Section titled “TypeScript DynamoDB プロジェクトを生成する”

このジェネレーターを実行@aws/nx-plugin:ts#dynamodb

pnpm nx g @aws/nx-plugin:ts#dynamodb
コマンドを組み立てる8

必須

ジェネレーターオプション8 オプション
name必須string

生成するDynamoDBプロジェクトの名前

directorystringデフォルト: packages

プロジェクトを保存するディレクトリ

frameworkenumデフォルト: electrodb

DynamoDB エンティティに使用するフレームワーク。

electrodb
infraenumデフォルト: dynamodb

DynamoDBテーブルのためにプロビジョニングするインフラストラクチャ。

dynamodbnone
iacenumデフォルト: inherit

優先するIaCプロバイダー。デフォルトでは、初期選択から継承されます。

inheritcdkterraform
subDirectorystring

プロジェクトが配置されるサブディレクトリ。デフォルトではプロジェクト名になります。

tableNamestring

DynamoDB テーブル名。指定しない場合は自動生成されます。

preferInstallDependenciesbooleanデフォルト: true

ジェネレーター実行後に依存関係のインストールを優先するかどうか。複数のジェネレーターをバッチ処理する際にインストールを延期する場合は false に設定します(後続のジェネレーターが Nx プロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。

ジェネレーターは <directory>/<name> ディレクトリに以下のプロジェクト構造を作成します:

  • Directorysrc
    • index.ts Project entry point and exports
    • client.ts DynamoDB client singleton and table name resolution
    • Directoryentities
      • example.ts Example ElectroDB entity definition
      • index.ts Entity exports
  • config.json Table configuration including GSI definitions and local development settings
  • package.json Project manifest defining the project’s package name and dependencies
  • project.json Project configuration and build targets

ローカル開発スクリプトは、すべての DynamoDB プロジェクト(TypeScript と Python の両方)で共有され、以下に一度生成されます:

  • Directorypackages/common/scripts/src/dynamodb
    • create-local-table.ts Creates the DynamoDB table in the local DynamoDB Local instance
    • pull-image.ts Pulls the DynamoDB Local image
    • start-container.ts Starts the DynamoDB Local container

このジェネレーターは、選択した iac に基づいてインフラストラクチャをコードとして提供するため、関連する CDK コンストラクトまたは Terraform モジュールを含む packages/common にプロジェクトを作成します。

共通のインフラストラクチャコードプロジェクトは、次のように構成されています:

  • Directorypackages/common/constructs
    • Directorysrc
      • Directoryapp/ プロジェクト/ジェネレーター固有のインフラストラクチャ用のコンストラクト
      • Directorycore/ app 内のコンストラクトによって再利用される汎用コンストラクト
      • index.ts app からコンストラクトをエクスポートするエントリーポイント
    • project.json プロジェクトのビルドターゲットと設定
  • Directorypackages/common/constructs/src
    • Directoryapp
      • Directorydynamodb
        • <name>.ts テーブル固有のインフラストラクチャ
    • Directorycore
      • dynamodb.ts 汎用 DynamoDB テーブルコンストラクト

デプロイされたプロジェクトはテーブル自体をプロビジョニングし、接続されたすべてのプロジェクトがそれを読み書きします:

Loading the diagram…

ジェネレーターは、DynamoDB Local インスタンスを起動してテーブルを作成する dev ターゲットを設定します。プロジェクトの dev ターゲットを使用してください:

Terminal window
pnpm nx dev <project-name>

これにより自動的に以下が実行されます:

  1. DynamoDB Local イメージをプル(pull-image ターゲット)
  2. コンテナを起動
  3. config.json で定義されたインデックスを持つローカルテーブルを作成

生成されたプロジェクトは、単一の DynamoDB テーブル上で型安全なエンティティモデリングを行うために ElectroDB を使用し、DynamoDB のシングルテーブル設計に従います。生成されたサンプルエンティティを出発点として、src/entities/ 配下にエンティティファイルを追加または更新してください。

エンティティ定義の例:

packages/my-table/src/entities/example.ts
import { Entity } from 'electrodb';
import { getDynamoDBClient, resolveTableName } from '../client.js';
export const createExampleEntity = async () =>
new Entity(
{
model: {
entity: 'example',
version: '1',
service: 'MyTable',
},
attributes: {
id: {
type: 'string',
required: true,
},
createdAt: {
type: 'string',
required: true,
default: () => new Date().toISOString(),
readOnly: true,
},
updatedAt: {
type: 'string',
required: true,
default: () => new Date().toISOString(),
watch: '*',
set: () => new Date().toISOString(),
},
},
indexes: {
primary: {
pk: {
field: 'pk',
composite: ['id'],
},
sk: {
field: 'sk',
composite: [],
},
},
},
},
{ client: getDynamoDBClient(), table: await resolveTableName() },
);

詳細については、ElectroDB エンティティドキュメントを参照してください。

生成された src/client.ts は、2つの主要なユーティリティをエクスポートします:

  • getDynamoDBClient() — キャッシュされたシングルトンの DynamoDBClient を返します。LOCAL_DEV=true の場合、ローカルの DynamoDB Local インスタンスに接続します。それ以外の場合は、デフォルトの認証情報チェーンを使用して AWS クライアントを作成します。
  • resolveTableName() — DynamoDB テーブル名を返します。LOCAL_DEV=true の場合、ローカルテーブル名定数を返します。それ以外の場合は、RUNTIME_CONFIG_APP_ID 環境変数を使用して AWS AppConfig から名前を取得し、後続の呼び出しのためにキャッシュします。

dev を停止する(例:Ctrl+C で)と、DynamoDB Local コンテナは自動的に削除されますが、名前付きボリュームは保持されるため、データは再起動後も保持されます。

グローバルセカンダリインデックスの追加/削除

Section titled “グローバルセカンダリインデックスの追加/削除”

GSI は、プロジェクトルートの config.jsontableConfig.globalSecondaryIndexes キーで定義されます。GSI キーのシングルテーブル設計命名規則に従って、各 GSI のエントリを追加してください:

config.json
{
...
"tableConfig": {
"globalSecondaryIndexes": [
{
"indexName": "gsi1pk-gsi1sk-index",
"partitionKey": "gsi1pk",
"sortKey": "gsi1sk"
},
{
"indexName": "gsi2pk-gsi2sk-index",
"partitionKey": "gsi2pk",
"sortKey": "gsi2sk"
}
]
}
}

sortKeyフィールドは、ハッシュキーのみのGSIの場合はオプションです。

この設定ファイルは、すべての利用者が読み取る唯一の信頼できる情報源です:

  • ローカル開発devconfig.jsonを読み取り、GSIリストに一致するようにローカルテーブルを作成または更新します
  • CDK — コンストラクトは合成時にconfig.jsonを読み取るため、GSIの変更は次回のcdk deployに反映されます
  • Terraform — モジュールはplan/apply時にconfig.jsonを読み取ります

任意の TypeScript プロジェクトで、DynamoDB パッケージからエンティティファクトリをインポートして直接使用します:

import { createExampleEntity } from '@my-scope/my-table';
const entity = await createExampleEntity();
const result = await entity.query.primary({ id: '123' }).go();

内部的には、createExampleEntity()resolveTableName() を呼び出して、実行時に AWS AppConfig からテーブル名を取得します。

DynamoDB ジェネレーターは、選択した iac に基づいて CDK または Terraform インフラストラクチャを作成します。

CDK コンストラクトは common/constructs に作成されます。使用例:

packages/infra/src/stacks/application-stack.ts
import { MyTable } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const table = new MyTable(this, 'Table');
}
}

これにより、以下の設定で DynamoDB テーブルがプロビジョニングされます:

  • pk(パーティションキー)と sk(ソートキー)、両方とも String
  • config.json で定義されたグローバルセカンダリインデックス
  • オンデマンド(PAY_PER_REQUEST)課金
  • 自動キーローテーション付きのカスタマー管理 KMS 暗号化
  • ポイントインタイムリカバリが有効
  • 削除保護が有効
  • AWS AppConfig の dynamodb 名前空間下の Runtime Config にテーブル名が登録される

テーブルは 2 つの独立したガードによって保護されているため、どちらか一方だけをオフにしてもデータを削除することはできません:

  • deletionProtection、DynamoDB によって強制されます。
  • RemovalPolicy.RETAIN、CloudFormation によって強制され、スタックから削除されてもテーブルをそのまま残します。

短期間の開発環境やプレビュースタックなど、テーブルの削除が想定される環境では保護を無効にします。

packages/infra/src/stacks/application-stack.ts
import { RemovalPolicy } from 'aws-cdk-lib';
import { MyTable } from '@my-scope/common-constructs';
const table = new MyTable(this, 'Table', {
deletionProtection: false,
removalPolicy: RemovalPolicy.DESTROY,
});

テーブルはデフォルトでオンデマンド(PAY_PER_REQUEST)課金です。予測可能で高スループットのワークロードの場合は、プロビジョニングされたキャパシティに切り替えます。

packages/infra/src/stacks/application-stack.ts
import { BillingMode } from 'aws-cdk-lib/aws-dynamodb';
import { MyTable } from '@my-scope/common-constructs';
const table = new MyTable(this, 'Table', {
billingMode: BillingMode.PROVISIONED,
readCapacity: 5,
writeCapacity: 5,
});

ポイントインタイムリカバリはデフォルトで有効になっており、過去 35 日間の任意の時点にテーブルを復元できます。

ポイントインタイムリカバリを無効にする

Section titled “ポイントインタイムリカバリを無効にする”
packages/infra/src/stacks/application-stack.ts
import { MyTable } from '@my-scope/common-constructs';
const table = new MyTable(this, 'Table', {
pointInTimeRecoverySpecification: { pointInTimeRecoveryEnabled: false },
});

テーブルはデフォルトでカスタマー管理 KMS キーで暗号化され、自動的に作成されます。暗号化を異なる方法で管理する場合は、AWS 管理キー、AWS 所有キー、または独自の KMS キーに切り替えます。

AWS があなたに代わって管理する共有 aws/dynamodb KMS キーを使用します。アカウントの KMS コンソールに表示され、リクエストごとに課金されますが、作成、ローテーション、削除するキーはありません。

packages/infra/src/stacks/application-stack.ts
import { TableEncryption } from 'aws-cdk-lib/aws-dynamodb';
import { MyTable } from '@my-scope/common-constructs';
const table = new MyTable(this, 'Table', {
encryption: TableEncryption.AWS_MANAGED,
});

AWS が完全に所有および管理するキーを使用します — 無料で、アカウントにキーが表示されることはありません。コンプライアンス上の理由でカスタマーまたはアカウントに表示されるキーが不要な場合の最もシンプルなオプションです。

packages/infra/src/stacks/application-stack.ts
import { TableEncryption } from 'aws-cdk-lib/aws-dynamodb';
import { MyTable } from '@my-scope/common-constructs';
const table = new MyTable(this, 'Table', {
encryption: TableEncryption.DEFAULT,
});
iac = terraform

すでにデプロイされているテーブルで、encryptionCUSTOMER_MANAGED から(AWS_MANAGED または DEFAULT のいずれかに)単一の terraform apply で変更すると失敗します:Terraform はテーブルを更新する前にカスタマー管理キーを破棄し、DynamoDB はキーがすでに削除保留中であるため更新を拒否します。

回避策として、まず AWS CLI を介してテーブルの暗号化を直接更新し、その後 Terraform に追いつかせて孤立したキーをクリーンアップします:

Terminal window
# For AWS_MANAGED:
aws dynamodb update-table --table-name <table-name> \
--sse-specification Enabled=true,SSEType=KMS,KMSMasterKeyId=alias/aws/dynamodb
# For DEFAULT:
aws dynamodb update-table --table-name <table-name> --sse-specification Enabled=false
# Then wait for this to report ENABLED (or for SSEDescription to disappear, for DEFAULT):
aws dynamodb describe-table --table-name <table-name> --query Table.SSEDescription.Status

次に、Terraform 設定で encryption を更新し、通常通り terraform apply を実行します — Terraform は、何も依存していない、すでに使用されていないキーを破棄するだけで済みます。

自動作成されるキーの代わりに、既存のカスタマー管理キーを提供します。キーは、独自のキーポリシーで DynamoDB サービスに必要な権限をすでに付与している必要があります。

packages/infra/src/stacks/application-stack.ts
import { Key } from 'aws-cdk-lib/aws-kms';
import { MyTable } from '@my-scope/common-constructs';
const key = Key.fromKeyArn(this, 'Key', 'arn:aws:kms:us-east-1:111111111111:key/my-key-id');
const table = new MyTable(this, 'Table', {
encryptionKey: key,
});

テーブルが独自のカスタマー管理 KMS キーを作成する場合(デフォルトで、独自のキーを提供していない場合のみ)、そのキーは自動キーローテーションがデフォルトで有効になっています。セキュリティポリシーで外部的にローテーションを管理する場合は無効にします。

暗号化キーのローテーションを無効にする
Section titled “暗号化キーのローテーションを無効にする”
packages/infra/src/stacks/application-stack.ts
import { MyTable } from '@my-scope/common-constructs';
const table = new MyTable(this, 'Table', {
enableKeyRotation: false,
});

connection ジェネレーターを使用して、このプロジェクトをワークスペース内の他のプロジェクトと統合します。このプロジェクトに関連する接続は以下の通りです:

tRPCAmazon DynamoDB
tRPC API to TypeScript DynamoDBtRPC API を DynamoDB テーブルに接続する
SmithyAmazon DynamoDB
Smithy API to TypeScript DynamoDBSmithy API を DynamoDB テーブルに接続する
Strands AgentsTypeScriptAmazon DynamoDB
TypeScript Agent to TypeScript DynamoDBTypeScript Agent を DynamoDB テーブルに接続する
Model Context ProtocolAmazon DynamoDB
MCP Server to TypeScript DynamoDBTypeScript MCP Server を DynamoDB テーブルに接続する