Skip to content

TypeScript DynamoDB

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

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

Section titled “TypeScript DynamoDBプロジェクトを生成する”
  1. インストール Nx Console VSCode Plugin まだインストールしていない場合
  2. VSCodeでNxコンソールを開く
  3. クリック Generate (UI) "Common Nx Commands"セクションで
  4. 検索 @aws/nx-plugin - ts#dynamodb
  5. 必須パラメータを入力
    • クリック Generate
    パラメータデフォルト説明
    name 必須string-生成するDynamoDBプロジェクトの名前
    directory stringpackagesプロジェクトを保存するディレクトリ
    subDirectory string-プロジェクトが配置されるサブディレクトリ。デフォルトではプロジェクト名になります。
    framework electrodbelectrodbDynamoDB エンティティに使用するフレームワーク。
    tableName string-DynamoDB テーブル名。指定しない場合は自動生成されます。
    infra dynamodb | nonedynamodbDynamoDBテーブルのためにプロビジョニングするインフラストラクチャ。
    iac inherit | cdk | terraforminherit優先するIaCプロバイダー。デフォルトでは、初期選択から継承されます。
    preferInstallDependencies booleantrueジェネレーター実行後に依存関係のインストールを優先するかどうか。複数のジェネレーターをバッチ処理する際にインストールを延期する場合は false に設定します(後続のジェネレーターが Nx プロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。

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

    • Directorysrc
      • index.ts プロジェクトのエントリーポイントとエクスポート
      • client.ts DynamoDBクライアントのシングルトンとテーブル名の解決
      • Directoryentities
        • example.ts ElectroDBエンティティ定義の例
        • index.ts エンティティのエクスポート
    • config.json GSI定義とローカル開発設定を含むテーブル設定
    • package.json プロジェクトのパッケージ名と依存関係を定義するプロジェクトマニフェスト
    • project.json プロジェクト設定とビルドターゲット

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

    • Directorypackages/common/scripts/src/dynamodb
      • create-local-table.ts ローカルのDynamoDB Localインスタンスにテーブルを作成する
      • pull-image.ts DynamoDB Localイメージをプルする
      • start-container.ts DynamoDB Localコンテナを起動する

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

    共通のInfrastructure as Codeプロジェクトは以下の構造を持ちます:

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

    ジェネレーターは、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名前空間下のランタイム設定にテーブル名が登録

    削除保護はデフォルトで有効になっており、誤ってテーブルを削除することを防ぎます。

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

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

    テーブルはデフォルトでオンデマンド(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キーは、デフォルトで自動キーローテーションが有効になっています。セキュリティポリシーで外部的にローテーションを管理している場合は無効にします。

    暗号化キーのローテーションの無効化

    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テーブルに接続する