TypeScript DynamoDB
このジェネレーターは、Amazon DynamoDBをバックエンドとする新しいTypeScript DynamoDBプロジェクトを作成し、型安全なエンティティモデリングにはElectroDBを使用します。AWS CDKまたはTerraformを使用してDynamoDBテーブルをプロビジョニングおよび管理するために必要なアプリケーションコードとインフラストラクチャを生成し、シングルテーブル設計のサポートとDynamoDB Localによる組み込みのローカル開発環境を提供します。
TypeScript DynamoDBプロジェクトを生成する
Section titled “TypeScript DynamoDBプロジェクトを生成する”- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - ts#dynamodb - 必須パラメータを入力
- クリック
Generate
pnpm nx g @aws/nx-plugin:ts#dynamodbyarn nx g @aws/nx-plugin:ts#dynamodbnpx nx g @aws/nx-plugin:ts#dynamodbbunx nx g @aws/nx-plugin:ts#dynamodb| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
| 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 プロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。 |
ジェネレーターの出力
Section titled “ジェネレーターの出力”ジェネレーターは、<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コンテナを起動する
インフラストラクチャ
Section titled “インフラストラクチャ”このジェネレータは選択した 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/terraform
Directorysrc
Directoryapp/ プロジェクト/ジェネレータ固有のインフラストラクチャ用Terraformモジュール
- …
Directorycore/
app内のモジュールで再利用される汎用モジュール- …
- project.json プロジェクトのビルドターゲットと設定
Directorypackages/common/constructs/src
Directoryapp
Directorydynamodb
- <name>.ts テーブル固有のインフラストラクチャ
Directorycore
- dynamodb.ts 汎用 DynamoDB テーブルコンストラクト
Directorypackages/common/terraform/src
Directoryapp
Directorydynamodb
Directory<name>
- <name>.tf テーブル固有のモジュール
Directorycore
Directorydynamodb
- dynamodb.tf 汎用 DynamoDB モジュール
ローカル開発
Section titled “ローカル開発”ローカルDynamoDBの起動
Section titled “ローカルDynamoDBの起動”ジェネレーターは、DynamoDB Local インスタンスを起動してテーブルを作成する dev ターゲットを設定します。プロジェクトの dev ターゲットを使用します:
pnpm nx dev <project-name>yarn nx dev <project-name>npx nx dev <project-name>bunx nx dev <project-name>これにより自動的に以下が実行されます:
- DynamoDB Local イメージをプル(
pull-imageターゲット) - コンテナを起動
config.jsonで定義されたインデックスを持つローカルテーブルを作成
データモデリング
Section titled “データモデリング”生成されたプロジェクトは、単一のDynamoDBテーブル上で型安全なエンティティモデリングを行うためにElectroDBを使用し、DynamoDBのシングルテーブル設計に従います。生成されたサンプルエンティティを出発点として、src/entities/配下にエンティティファイルを追加または更新してください。
エンティティ定義の例:
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エンティティドキュメントを参照してください。
DynamoDBクライアントの使用
Section titled “DynamoDBクライアントの使用”生成されたsrc/client.tsは、2つの主要なユーティリティをエクスポートします:
getDynamoDBClient()— キャッシュされたシングルトンのDynamoDBClientを返します。LOCAL_DEV=trueの場合、ローカルのDynamoDB Localインスタンスに接続します。それ以外の場合は、デフォルトの認証情報チェーンを使用してAWSクライアントを作成します。resolveTableName()— DynamoDBテーブル名を返します。LOCAL_DEV=trueの場合、ローカルテーブル名定数を返します。それ以外の場合は、RUNTIME_CONFIG_APP_ID環境変数を使用してAWS AppConfigから名前を取得し、後続の呼び出しのためにキャッシュします。
ローカルDynamoDBの停止
Section titled “ローカルDynamoDBの停止”dev を停止する(例:Ctrl+C で)と、DynamoDB Local コンテナは自動的に削除されますが、名前付きボリュームは保持されるため、再起動後もデータは永続化されます。
グローバルセカンダリインデックスの追加/削除
Section titled “グローバルセカンダリインデックスの追加/削除”GSIは、プロジェクトルートのconfig.jsonのtableConfig.globalSecondaryIndexesキー配下で定義されます。各GSIに対してエントリを追加し、GSIキーのシングルテーブル設計命名規則に従ってください:
{ ... "tableConfig": { "globalSecondaryIndexes": [ { "indexName": "gsi1pk-gsi1sk-index", "partitionKey": "gsi1pk", "sortKey": "gsi1sk" }, { "indexName": "gsi2pk-gsi2sk-index", "partitionKey": "gsi2pk", "sortKey": "gsi2sk" } ] }}sortKeyフィールドは、ハッシュキーのみのGSIの場合はオプションです。
この設定ファイルは、すべての利用者が読み取る唯一の信頼できる情報源です:
- ローカル開発 —
devはconfig.jsonを読み取り、GSIリストに一致するようにローカルテーブルを作成または更新します - CDK — コンストラクトは合成時に
config.jsonを読み取るため、GSIの変更は次回のcdk deployに反映されます - Terraform — モジュールはplan/apply時に
config.jsonを読み取ります
デプロイごとに1つのGSI
Section titled “デプロイごとに1つのGSI”テーブルへの接続
Section titled “テーブルへの接続”任意のTypeScriptプロジェクトで、DynamoDBパッケージからエンティティファクトリをインポートして直接使用できます:
import { createExampleEntity } from ':my-scope/my-table';
const entity = await createExampleEntity();const result = await entity.query.primary({ id: '123' }).go();テーブルのデプロイ
Section titled “テーブルのデプロイ”DynamoDBジェネレーターは、選択したiacに基づいてCDKまたはTerraformインフラストラクチャを作成します。
CDKコンストラクトはcommon/constructsに作成されます。使用例:
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名前空間下のランタイム設定にテーブル名が登録
Terraformモジュールはcommon/terraformに作成されます。使用例:
module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table"}これにより、以下の設定でDynamoDBテーブルがプロビジョニングされます:
pk(パーティションキー)とsk(ソートキー)、両方ともString型config.jsonで定義されたグローバルセカンダリインデックス- オンデマンド(
PAY_PER_REQUEST)課金 - 自動キーローテーション付きのカスタマー管理KMS暗号化
- ポイントインタイムリカバリが有効
- 削除保護が有効
- ランタイム設定にテーブル名が登録
アクセス権限の付与
Section titled “アクセス権限の付与”Lambda 関数が DynamoDB テーブルにアクセスできるようにするには、インフラストラクチャで必要な権限を付与します。
テーブルコンストラクトで grantReadWriteData を呼び出します。これにより、Lambda 実行ロールに必要な DynamoDB と KMS の両方の権限が付与されます:
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);});Lambda 実行ロールに DynamoDB テーブルとその KMS 暗号化キーへのアクセス権限を付与します:
module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table"}
resource "aws_iam_role_policy" "dynamodb_access" { role = module.my_api.lambda_role_name
policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem", ] Resource = [ module.my_table.table_arn, "${module.my_table.table_arn}/index/*", ] }, { Effect = "Allow" Action = [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ] Resource = [module.my_table.kms_key_arn] }, ] })}削除保護はデフォルトで有効になっており、誤ってテーブルを削除することを防ぎます。
削除保護の無効化
Section titled “削除保護の無効化”短期間の開発環境やプレビュースタックなど、テーブルの削除が想定される環境では無効にします。
import { MyTable } from ':my-scope/common-constructs';
const table = new MyTable(this, 'Table', { deletionProtection: false,});module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table" deletion_protection_enabled = false}テーブルはデフォルトでオンデマンド(PAY_PER_REQUEST)課金になります。予測可能で高スループットのワークロードには、プロビジョニングされたキャパシティに切り替えます。
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,});module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table" billing_mode = "PROVISIONED"}ポイントインタイムリカバリ
Section titled “ポイントインタイムリカバリ”ポイントインタイムリカバリはデフォルトで有効になっており、過去35日間の任意の時点にテーブルを復元できます。
ポイントインタイムリカバリの無効化
Section titled “ポイントインタイムリカバリの無効化”import { MyTable } from ':my-scope/common-constructs';
const table = new MyTable(this, 'Table', { pointInTimeRecoverySpecification: { pointInTimeRecoveryEnabled: false },});module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table" point_in_time_recovery_enabled = false}暗号化キーのローテーション
Section titled “暗号化キーのローテーション”テーブルの暗号化に使用されるKMSキーは、デフォルトで自動キーローテーションが有効になっています。セキュリティポリシーで外部的にローテーションを管理している場合は無効にします。
暗号化キーのローテーションの無効化
Section titled “暗号化キーのローテーションの無効化”import { MyTable } from ':my-scope/common-constructs';
const table = new MyTable(this, 'Table', { enableKeyRotation: false,});module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table" enable_key_rotation = false}connectionジェネレータを使用して、このプロジェクトをワークスペース内の他のプロジェクトと統合できます。このプロジェクトに関連する接続は以下の通りです: