Bỏ qua để đến nội dung

TypeScript DynamoDB

Generator này tạo một dự án TypeScript DynamoDB mới được hỗ trợ bởi Amazon DynamoDB, sử dụng ElectroDB để mô hình hóa thực thể an toàn kiểu. Nó tạo ra mã ứng dụng và cơ sở hạ tầng cần thiết để cung cấp và quản lý bảng DynamoDB bằng AWS CDK hoặc Terraform, với hỗ trợ thiết kế bảng đơn và phát triển cục bộ tích hợp sẵn thông qua DynamoDB Local.

  1. Cài đặt Nx Console VSCode Plugin nếu bạn chưa cài đặt
  2. Mở Nx Console trong VSCode
  3. Nhấp Generate (UI) trong phần "Common Nx Commands"
  4. Tìm kiếm @aws/nx-plugin - ts#dynamodb
  5. Điền các tham số bắt buộc
    • Nhấp Generate
    Tham số Kiểu Mặc định Mô tả
    name Bắt buộc string - Tên của dự án DynamoDB cần tạo
    directory string packages Thư mục để lưu trữ dự án.
    subDirectory string - Thư mục con mà dự án được đặt trong đó. Mặc định là tên dự án.
    framework electrodb electrodb Framework sử dụng cho các entity DynamoDB.
    tableName string - Tên bảng DynamoDB. Tự động tạo nếu không chỉ định.
    infra dynamodb | none dynamodb Cơ sở hạ tầng để cung cấp cho bảng DynamoDB.
    iac inherit | cdk | terraform inherit Nhà cung cấp IaC ưa thích. Mặc định giá trị này được kế thừa từ lựa chọn ban đầu của bạn.
    preferInstallDependencies boolean true Có nên cài đặt các dependencies sau khi generator chạy hay không. Đặt thành false để hoãn việc cài đặt khi chạy nhiều generator liên tiếp (việc cài đặt vẫn sẽ chạy nếu cần thiết để các generator tiếp theo có thể tính toán Nx project graph); cài đặt một lần vào cuối.

    Generator tạo cấu trúc dự án sau trong thư mục <directory>/<name>:

    • Thư mụcsrc
      • index.ts Điểm vào dự án và exports
      • client.ts Singleton client DynamoDB và phân giải tên bảng
      • Thư mụcentities
        • example.ts Định nghĩa thực thể ElectroDB mẫu
        • index.ts Exports thực thể
    • config.json Cấu hình bảng bao gồm định nghĩa GSI và cài đặt phát triển cục bộ
    • project.json Cấu hình dự án và các target build

    Các script phát triển cục bộ được chia sẻ trên tất cả các dự án DynamoDB (cả TypeScript và Python) và được tạo một lần vào:

    • Thư mụcpackages/common/scripts/src/dynamodb
      • create-local-table.ts Tạo bảng DynamoDB trong phiên bản DynamoDB Local cục bộ
      • pull-image.ts Tải image DynamoDB Local
      • start-container.ts Khởi động container DynamoDB Local

    Vì generator này cung cấp infrastructure as code dựa trên iacProvider bạn đã chọn, nó sẽ tạo một dự án trong packages/common bao gồm các CDK constructs hoặc Terraform modules liên quan.

    Dự án infrastructure as code chung được cấu trúc như sau:

    • Thư mụcpackages/common/constructs
      • Thư mụcsrc
        • Thư mụcapp/ Constructs cho infrastructure cụ thể của một dự án/generator
        • Thư mụccore/ Constructs chung được tái sử dụng bởi các constructs trong app
        • index.ts Entry point xuất các constructs từ app
      • project.json Các build targets và cấu hình của dự án
    • Thư mụcpackages/common/constructs/src
      • Thư mụcapp
        • Thư mụcdynamodb
          • <name>.ts Cơ sở hạ tầng cụ thể cho bảng của bạn
      • Thư mụccore
        • dynamodb.ts Construct bảng DynamoDB chung

    Generator cấu hình một target dev để khởi động một instance DynamoDB Local và tạo bảng. Sử dụng target dev của dự án:

    Terminal window
    pnpm nx dev <project-name>

    Điều này tự động:

    1. Kéo image DynamoDB Local (target pull-image)
    2. Khởi động một container
    3. Tạo một bảng local với các index được định nghĩa trong config.json

    Dự án được tạo sử dụng ElectroDB để mô hình hóa thực thể an toàn kiểu trên một bảng DynamoDB đơn, tuân theo thiết kế bảng đơn của DynamoDB. Thêm hoặc cập nhật các tệp thực thể trong src/entities/, sử dụng thực thể mẫu được tạo làm điểm khởi đầu.

    Ví dụ định nghĩa thực thể:

    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() },
    );

    Để biết thêm chi tiết, xem tài liệu thực thể ElectroDB.

    Tệp src/client.ts được tạo xuất hai tiện ích chính:

    • getDynamoDBClient() — trả về một singleton DynamoDBClient được lưu trong bộ nhớ cache. Khi LOCAL_DEV=true, kết nối đến phiên bản DynamoDB Local cục bộ; nếu không, tạo một client AWS sử dụng chuỗi thông tin xác thực mặc định.
    • resolveTableName() — trả về tên bảng DynamoDB. Khi LOCAL_DEV=true, trả về hằng số tên bảng cục bộ; nếu không, lấy tên từ AWS AppConfig sử dụng biến môi trường RUNTIME_CONFIG_APP_ID và lưu vào bộ nhớ cache cho các lần gọi tiếp theo.

    Dừng dev (ví dụ: bằng Ctrl+C) sẽ tự động xóa container DynamoDB Local, nhưng vẫn giữ lại named volume để dữ liệu của bạn được bảo toàn qua các lần khởi động lại.

    GSI được định nghĩa trong config.json tại thư mục gốc của dự án dưới khóa tableConfig.globalSecondaryIndexes. Thêm một mục cho mỗi GSI, tuân theo quy ước đặt tên thiết kế bảng đơn cho các khóa GSI:

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

    Trường sortKey là tùy chọn đối với các GSI chỉ có hash-key.

    Tệp cấu hình này là nguồn sự thật duy nhất được đọc bởi tất cả các consumer:

    • Local developmentdev đọc config.json và tạo hoặc cập nhật bảng cục bộ để khớp với danh sách GSI
    • CDK — construct đọc config.json tại thời điểm synth, do đó các thay đổi GSI sẽ được phản ánh trong lần cdk deploy tiếp theo
    • Terraform — module đọc config.json tại thời điểm plan/apply

    Trong bất kỳ dự án TypeScript nào, import các factory thực thể từ package DynamoDB của bạn và sử dụng chúng trực tiếp:

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

    Trình tạo DynamoDB tạo cơ sở hạ tầng CDK hoặc Terraform dựa trên iac bạn đã chọn.

    CDK construct được tạo trong common/constructs. Ví dụ sử dụng:

    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');
    }
    }

    Điều này cung cấp một bảng DynamoDB với:

    • pk (partition key) và sk (sort key), cả hai đều là kiểu String
    • Global Secondary Indexes như được định nghĩa trong config.json
    • Thanh toán theo yêu cầu (PAY_PER_REQUEST)
    • Mã hóa KMS do khách hàng quản lý với tự động xoay khóa
    • Khôi phục theo thời điểm được bật
    • Bảo vệ xóa được bật
    • Tên bảng được đăng ký trong Runtime Config dưới namespace dynamodb trong AWS AppConfig

    Để cho phép các hàm Lambda truy cập bảng DynamoDB, hãy cấp các quyền cần thiết trong cơ sở hạ tầng của bạn.

    Gọi grantReadWriteData trên table construct. Điều này cấp cả quyền DynamoDB và KMS cần thiết cho vai trò thực thi Lambda:

    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);
    });

    Bảo vệ xóa được bật mặc định để ngăn chặn việc xóa bảng do nhầm lẫn.

    Tắt nó cho các môi trường mà việc xóa bảng được mong đợi, chẳng hạn như các stack phát triển hoặc xem trước tồn tại ngắn hạn.

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

    Bảng mặc định sử dụng thanh toán theo yêu cầu (PAY_PER_REQUEST). Chuyển sang dung lượng được cung cấp cho các khối lượng công việc có thông lượng cao và có thể dự đoán.

    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,
    });

    Khôi phục theo thời điểm được bật mặc định, cho phép bạn khôi phục bảng về bất kỳ thời điểm nào trong 35 ngày qua.

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

    Khóa KMS được sử dụng để mã hóa bảng có tự động xoay khóa được bật mặc định. Tắt nó nếu chính sách bảo mật của bạn quản lý việc xoay khóa từ bên ngoài.

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

    Sử dụng generator connection để tích hợp dự án này với các dự án khác trong workspace của bạn. Các kết nối sau liên quan đến dự án này:

    tRPC Amazon DynamoDB
    tRPC API to TypeScript DynamoDB Kết nối tRPC API với bảng DynamoDB
    Smithy Amazon DynamoDB
    Smithy API to TypeScript DynamoDB Kết nối Smithy API với bảng DynamoDB
    Strands Agents TypeScript Amazon DynamoDB
    TypeScript Agent to TypeScript DynamoDB Kết nối TypeScript Agent với bảng DynamoDB
    Model Context Protocol Amazon DynamoDB
    MCP Server to TypeScript DynamoDB Kết nối TypeScript MCP Server với bảng DynamoDB