Pular para o conteúdo

TypeScript DynamoDB

Este gerador cria um novo projeto TypeScript DynamoDB apoiado pelo Amazon DynamoDB, usando ElectroDB para modelagem de entidades com segurança de tipos. Ele gera o código da aplicação e a infraestrutura necessária para provisionar e gerenciar uma tabela DynamoDB usando AWS CDK ou Terraform, com suporte a design de tabela única e desenvolvimento local integrado via DynamoDB Local.

  1. Instale o Nx Console VSCode Plugin se ainda não o fez
  2. Abra o console Nx no VSCode
  3. Clique em Generate (UI) na seção "Common Nx Commands"
  4. Procure por @aws/nx-plugin - ts#dynamodb
  5. Preencha os parâmetros obrigatórios
    • Clique em Generate
    Parâmetro Tipo Padrão Descrição
    name Obrigatório string - Nome do projeto DynamoDB a ser gerado
    directory string packages O diretório onde armazenar o projeto.
    subDirectory string - O subdiretório onde o projeto é colocado. Por padrão, este é o nome do projeto.
    framework electrodb electrodb O framework a ser usado para entidades DynamoDB.
    tableName string - O nome da tabela DynamoDB. Gerado automaticamente se não especificado.
    infra dynamodb | none dynamodb Infraestrutura a provisionar para a tabela DynamoDB.
    iac inherit | cdk | terraform inherit O provedor IaC preferido. Por padrão, isso é herdado da sua seleção inicial.
    preferInstallDependencies boolean true Se deve preferir instalar dependências após a execução do gerador. Defina como false para adiar a instalação ao executar múltiplos geradores em lote (uma instalação ainda é executada se necessário para que geradores subsequentes possam calcular o grafo de projetos Nx); instale uma vez no final.

    O gerador cria a seguinte estrutura de projeto no diretório <directory>/<name>:

    • Directorysrc
      • index.ts Ponto de entrada do projeto e exportações
      • client.ts Singleton do cliente DynamoDB e resolução do nome da tabela
      • Directoryentities
        • example.ts Definição de entidade ElectroDB de exemplo
        • index.ts Exportações de entidades
    • config.json Configuração da tabela incluindo definições de GSI e configurações de desenvolvimento local
    • project.json Configuração do projeto e alvos de build

    Os scripts de desenvolvimento local são compartilhados entre todos os projetos DynamoDB (tanto TypeScript quanto Python) e gerados uma vez em:

    • Directorypackages/common/scripts/src/dynamodb
      • create-local-table.ts Cria a tabela DynamoDB na instância local do DynamoDB Local
      • pull-image.ts Baixa a imagem do DynamoDB Local
      • start-container.ts Inicia o contêiner do DynamoDB Local

    Como este gerador fornece infraestrutura como código com base no iacProvider escolhido, ele criará um projeto em packages/common que inclui os constructs CDK ou módulos Terraform relevantes.

    O projeto comum de infraestrutura como código está estruturado da seguinte forma:

    • Directorypackages/common/constructs
      • Directorysrc
        • Directoryapp/ Constructs para infraestrutura específica de um projeto/gerador
        • Directorycore/ Constructs genéricos reutilizados pelos constructs em app
        • index.ts Ponto de entrada exportando os constructs de app
      • project.json Metas de build e configuração do projeto
    • Directorypackages/common/constructs/src
      • Directoryapp
        • Directorydynamodb
          • <name>.ts Infraestrutura específica para sua tabela
      • Directorycore
        • dynamodb.ts Construto genérico de tabela DynamoDB

    O gerador configura um target dev que inicia uma instância do DynamoDB Local e cria a tabela. Use o target dev do projeto:

    Terminal window
    pnpm nx dev <project-name>

    Isso automaticamente:

    1. Baixa a imagem do DynamoDB Local (target pull-image)
    2. Inicia um contêiner
    3. Cria uma tabela local com os índices definidos em config.json

    O projeto gerado usa ElectroDB para modelagem de entidades com segurança de tipos em uma única tabela DynamoDB, seguindo o design de tabela única do DynamoDB. Adicione ou atualize arquivos de entidade em src/entities/, usando a entidade de exemplo gerada como ponto de partida.

    Exemplo de definição de entidade:

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

    Para mais detalhes, consulte a documentação de entidades do ElectroDB.

    O arquivo src/client.ts gerado exporta dois utilitários principais:

    • getDynamoDBClient() — retorna um singleton DynamoDBClient em cache. Quando LOCAL_DEV=true, conecta-se à instância local do DynamoDB Local; caso contrário, cria um cliente AWS usando a cadeia de credenciais padrão.
    • resolveTableName() — retorna o nome da tabela DynamoDB. Quando LOCAL_DEV=true, retorna a constante do nome da tabela local; caso contrário, busca o nome do AWS AppConfig usando a variável de ambiente RUNTIME_CONFIG_APP_ID e o armazena em cache para chamadas subsequentes.

    Parar o dev (por exemplo, com Ctrl+C) remove automaticamente o contêiner DynamoDB Local, mas preserva o volume nomeado para que seus dados persistam entre reinicializações.

    GSIs são definidos em config.json na raiz do projeto sob a chave tableConfig.globalSecondaryIndexes. Adicione uma entrada para cada GSI, seguindo a convenção de nomenclatura de design de tabela única para chaves GSI:

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

    O campo sortKey é opcional para GSIs somente com chave de hash.

    Este arquivo de configuração é a única fonte de verdade lida por todos os consumidores:

    • Desenvolvimento localdevconfig.json e cria ou atualiza a tabela local para corresponder à lista de GSI
    • CDK — o construct lê config.json no momento da síntese, então as mudanças de GSI são refletidas no próximo cdk deploy
    • Terraform — o módulo lê config.json no momento do plan/apply

    Em qualquer projeto TypeScript, importe as fábricas de entidades do seu pacote DynamoDB e use-as diretamente:

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

    O gerador DynamoDB cria infraestrutura CDK ou Terraform com base no seu iac selecionado.

    O construtor CDK é criado em common/constructs. Exemplo de uso:

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

    Isso provisiona uma tabela DynamoDB com:

    • pk (chave de partição) e sk (chave de ordenação), ambas do tipo String
    • Índices Secundários Globais conforme definido em config.json
    • Cobrança sob demanda (PAY_PER_REQUEST)
    • Criptografia KMS gerenciada pelo cliente com rotação automática de chaves
    • Recuperação point-in-time habilitada
    • Proteção contra exclusão habilitada
    • Nome da tabela registrado no Runtime Config sob o namespace dynamodb no AWS AppConfig

    Para permitir que funções Lambda acessem a tabela DynamoDB, conceda as permissões necessárias em sua infraestrutura.

    Chame grantReadWriteData no construto da tabela. Isso concede as permissões do DynamoDB e KMS necessárias para a função de execução do 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);
    });

    A proteção contra exclusão está habilitada por padrão para prevenir a exclusão acidental da tabela.

    Desabilite-a para ambientes onde a exclusão da tabela é esperada, como stacks de desenvolvimento ou preview de curta duração.

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

    A tabela usa por padrão cobrança sob demanda (PAY_PER_REQUEST). Mude para capacidade provisionada para cargas de trabalho previsíveis e de alto throughput.

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

    A recuperação point-in-time está habilitada por padrão, permitindo que você restaure a tabela para qualquer ponto nos últimos 35 dias.

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

    A chave KMS usada para criptografar a tabela tem rotação automática de chaves habilitada por padrão. Desabilite-a se sua política de segurança gerencia a rotação externamente.

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

    Use o gerador connection para integrar este projeto com outros em seu workspace. As seguintes conexões envolvem este projeto:

    tRPC Amazon DynamoDB
    API tRPC para TypeScript DynamoDB Conecte uma API tRPC a uma tabela DynamoDB
    Smithy Amazon DynamoDB
    API Smithy para TypeScript DynamoDB Conecte uma API Smithy a uma tabela DynamoDB
    Strands Agents TypeScript Amazon DynamoDB
    TypeScript Agent para TypeScript DynamoDB Conecte um TypeScript Agent a uma tabela DynamoDB
    Model Context Protocol Amazon DynamoDB
    Servidor MCP para TypeScript DynamoDB Conecte um Servidor MCP TypeScript a uma tabela DynamoDB