跳转到内容

TypeScript DynamoDB

此生成器创建一个由 Amazon DynamoDB 支持的新 TypeScript DynamoDB 项目,使用 ElectroDB 进行类型安全的实体建模。它生成应用程序代码和基础设施,用于使用 AWS CDK 或 Terraform 配置和管理 DynamoDB 表,支持单表设计,并通过 DynamoDB Local 内置本地开发功能。

  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> 目录中创建以下项目结构:

    • 文件夹src
      • index.ts 项目入口点和导出
      • client.ts DynamoDB 客户端单例和表名解析
      • 文件夹entities
        • example.ts 示例 ElectroDB 实体定义
        • index.ts 实体导出
    • config.json 表配置,包括 GSI 定义和本地开发设置
    • project.json 项目配置和构建目标

    本地开发脚本在所有 DynamoDB 项目(TypeScript 和 Python)之间共享,并生成一次到:

    • 文件夹packages/common/scripts/src/dynamodb
      • create-local-table.ts 在本地 DynamoDB Local 实例中创建 DynamoDB 表
      • pull-image.ts 拉取 DynamoDB Local 镜像
      • start-container.ts 启动 DynamoDB Local 容器

    由于该生成器会根据您选择的 iacProvider 以基础设施即代码的形式输出,它将在 packages/common 目录下创建一个包含相关 CDK 构造体或 Terraform 模块的项目。

    通用的基础设施即代码项目结构如下:

    • 文件夹packages/common/constructs
      • 文件夹src
        • 文件夹app/ 针对特定项目/生成器的基础设施构造体
        • 文件夹core/ app 目录构造体重用的通用构造体
        • index.ts 导出 app 目录构造体的入口文件
      • project.json 项目构建目标与配置
    • 文件夹packages/common/constructs/src
      • 文件夹app
        • 文件夹dynamodb
          • <name>.ts 特定于您的表的基础设施
      • 文件夹core
        • dynamodb.ts 通用 DynamoDB 表构造

    生成器配置了一个 dev 目标,用于启动 DynamoDB Local 实例并创建表。使用项目的 dev 目标:

    Terminal window
    pnpm nx dev <project-name>

    这将自动:

    1. 拉取 DynamoDB Local 镜像(pull-image 目标)
    2. 启动容器
    3. 使用 config.json 中定义的索引创建本地表

    生成的项目使用 ElectroDB 在单个 DynamoDB 表上进行类型安全的实体建模,遵循 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 导出两个关键实用程序:

    • getDynamoDBClient() — 返回缓存的单例 DynamoDBClient。当 LOCAL_DEV=true 时,连接到本地 DynamoDB Local 实例;否则使用默认凭证链创建 AWS 客户端。
    • resolveTableName() — 返回 DynamoDB 表名。当 LOCAL_DEV=true 时,返回本地表名常量;否则使用 RUNTIME_CONFIG_APP_ID 环境变量从 AWS AppConfig 获取名称,并为后续调用缓存它。

    停止 dev(例如使用 Ctrl+C)会自动删除 DynamoDB Local 容器,但会保留命名卷,以便您的数据在重启后保持不变。

    GSI 在项目根目录的 config.json 中的 tableConfig.globalSecondaryIndexes 键下定义。为每个 GSI 添加一个条目,遵循单表设计的 GSI 键命名约定:

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

    对于仅使用哈希键的 GSI,sortKey 字段是可选的。

    此配置文件是所有使用者读取的单一数据源:

    • 本地开发dev 读取 config.json 并创建或更新本地表以匹配 GSI 列表
    • CDK — 构造在合成时读取 config.json,因此 GSI 更改会在下次 cdk deploy 时反映出来
    • Terraform — 模块在计划/应用时读取 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 天内的任何时间点。

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

    用于加密表的 KMS 密钥默认启用自动密钥轮换。如果您的安全策略在外部管理轮换,可以禁用它。

    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 表