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 string packages プロジェクトを保存するディレクトリ
    subDirectory string - プロジェクトが配置されるサブディレクトリ。デフォルトではプロジェクト名になります。
    framework electrodb electrodb DynamoDB エンティティに使用するフレームワーク。
    tableName string - DynamoDB テーブル名。指定しない場合は自動生成されます。
    infra dynamodb | none dynamodb DynamoDBテーブルのためにプロビジョニングするインフラストラクチャ。
    iac inherit | cdk | terraform inherit 優先するIaCプロバイダー。デフォルトでは、初期選択から継承されます。
    preferInstallDependencies boolean true ジェネレーター実行後に依存関係のインストールを優先するかどうか。複数のジェネレーターをバッチ処理する際にインストールを延期する場合は false に設定します(後続のジェネレーターが Nx プロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。

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

    • Directorysrc
      • index.ts プロジェクトのエントリーポイントとエクスポート
      • client.ts DynamoDBクライアントのシングルトンとテーブル名の解決
      • Directoryentities
        • example.ts ElectroDBエンティティ定義の例
        • index.ts エンティティのエクスポート
    • config.json GSI定義とローカル開発設定を含むテーブル設定
    • 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コンテナを起動する

    このジェネレータは選択した iacProvider に基づいて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();

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

    Lambda 関数が DynamoDB テーブルにアクセスできるようにするには、インフラストラクチャで必要な権限を付与します。

    テーブルコンストラクトで grantReadWriteData を呼び出します。これにより、Lambda 実行ロールに必要な DynamoDB と KMS の両方の権限が付与されます:

    packages/infra/src/stacks/application-stack.ts
    import { MyTable } from ':my-scope/common-constructs';
    const table = new MyTable(this, 'Table');
    const api = new Api(this, 'Api', {
    integrations: Api.defaultIntegrations(this).build(),
    });
    Object.entries(api.integrations).forEach(([, integration]) => {
    table.grantReadWriteData(integration.handler);
    });

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

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

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

    tRPC Amazon DynamoDB
    tRPC API to TypeScript DynamoDB tRPC APIをDynamoDBテーブルに接続する
    Smithy Amazon DynamoDB
    Smithy API to TypeScript DynamoDB Smithy APIをDynamoDBテーブルに接続する
    Strands Agents TypeScript Amazon DynamoDB
    TypeScript Agent to TypeScript DynamoDB TypeScript AgentをDynamoDBテーブルに接続する
    Model Context Protocol Amazon DynamoDB
    MCP Server to TypeScript DynamoDB TypeScript MCP ServerをDynamoDBテーブルに接続する