Ir al contenido

TypeScript DynamoDB

Este generador crea un nuevo proyecto de TypeScript DynamoDB respaldado por Amazon DynamoDB, utilizando ElectroDB para el modelado de entidades con seguridad de tipos. Genera el código de aplicación y la infraestructura necesaria para aprovisionar y gestionar una tabla DynamoDB usando AWS CDK o Terraform, con soporte para diseño de tabla única y desarrollo local integrado mediante DynamoDB Local.

  1. Instale el Nx Console VSCode Plugin si aún no lo ha hecho
  2. Abra la consola Nx en VSCode
  3. Haga clic en Generate (UI) en la sección "Common Nx Commands"
  4. Busque @aws/nx-plugin - ts#dynamodb
  5. Complete los parámetros requeridos
    • Haga clic en Generate
    Parámetro Tipo Predeterminado Descripción
    name Requerido string - Nombre del proyecto DynamoDB a generar
    directory string packages El directorio donde almacenar el proyecto.
    subDirectory string - El subdirectorio donde se coloca el proyecto. Por defecto es el nombre del proyecto.
    framework electrodb electrodb El framework a utilizar para las entidades de DynamoDB.
    tableName string - El nombre de la tabla de DynamoDB. Se genera automáticamente si no se especifica.
    infra dynamodb | none dynamodb Infraestructura a aprovisionar para la tabla DynamoDB.
    iac inherit | cdk | terraform inherit El proveedor de IaC preferido. Por defecto, se hereda de tu selección inicial.
    preferInstallDependencies boolean true Si se prefiere instalar las dependencias después de que se ejecute el generador. Establecer en false para diferir la instalación al ejecutar múltiples generadores en lote (la instalación aún se ejecuta si es necesario para que los generadores subsiguientes puedan calcular el grafo de proyectos de Nx); instalar una vez al final.

    El generador crea la siguiente estructura de proyecto en el directorio <directory>/<name>:

    • Directoriosrc
      • index.ts Punto de entrada del proyecto y exportaciones
      • client.ts Singleton del cliente DynamoDB y resolución del nombre de tabla
      • Directorioentities
        • example.ts Definición de entidad ElectroDB de ejemplo
        • index.ts Exportaciones de entidades
    • config.json Configuración de tabla incluyendo definiciones de GSI y configuración de desarrollo local
    • project.json Configuración del proyecto y objetivos de compilación

    Los scripts de desarrollo local se comparten entre todos los proyectos de DynamoDB (tanto TypeScript como Python) y se generan una vez en:

    • Directoriopackages/common/scripts/src/dynamodb
      • create-local-table.ts Crea la tabla DynamoDB en la instancia local de DynamoDB Local
      • pull-image.ts Descarga la imagen de DynamoDB Local
      • start-container.ts Inicia el contenedor de DynamoDB Local

    Dado que este generador proporciona infraestructura como código basada en tu proveedor de iacProvider seleccionado, creará un proyecto en packages/common que incluye los constructos CDK o módulos de Terraform correspondientes.

    El proyecto común de infraestructura como código tiene la siguiente estructura:

    • Directoriopackages/common/constructs
      • Directoriosrc
        • Directorioapp/ Constructos para infraestructura específica de un proyecto/generador
        • Directoriocore/ Constructos genéricos reutilizados por los constructos en app
        • index.ts Punto de entrada que exporta los constructos de app
      • project.json Objetivos de compilación y configuración del proyecto
    • Directoriopackages/common/constructs/src
      • Directorioapp
        • Directoriodynamodb
          • <name>.ts Infraestructura específica para tu tabla
      • Directoriocore
        • dynamodb.ts Construcción genérica de tabla DynamoDB

    El generador configura un target dev que inicia una instancia de DynamoDB Local y crea la tabla. Usa el target dev del proyecto:

    Terminal window
    pnpm nx dev <project-name>

    Esto automáticamente:

    1. Descarga la imagen de DynamoDB Local (target pull-image)
    2. Inicia un contenedor
    3. Crea una tabla local con los índices definidos en config.json

    El proyecto generado utiliza ElectroDB para el modelado de entidades con seguridad de tipos en una única tabla DynamoDB, siguiendo el diseño de tabla única de DynamoDB. Agrega o actualiza archivos de entidad en src/entities/, utilizando la entidad de ejemplo generada como punto de partida.

    Ejemplo de definición de entidad:

    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 más detalles, consulta la documentación de entidades de ElectroDB.

    El archivo generado src/client.ts exporta dos utilidades clave:

    • getDynamoDBClient() — devuelve un singleton en caché de DynamoDBClient. Cuando LOCAL_DEV=true, se conecta a la instancia local de DynamoDB Local; de lo contrario, crea un cliente AWS usando la cadena de credenciales predeterminada.
    • resolveTableName() — devuelve el nombre de la tabla DynamoDB. Cuando LOCAL_DEV=true, devuelve la constante del nombre de tabla local; de lo contrario, obtiene el nombre de AWS AppConfig usando la variable de entorno RUNTIME_CONFIG_APP_ID y lo almacena en caché para llamadas posteriores.

    Detener dev (por ejemplo, con Ctrl+C) elimina automáticamente el contenedor de DynamoDB Local, pero conserva el volumen nombrado para que tus datos persistan entre reinicios.

    Agregar/Eliminar Índices Secundarios Globales

    Sección titulada «Agregar/Eliminar Índices Secundarios Globales»

    Los GSI se definen en config.json en la raíz del proyecto bajo la clave tableConfig.globalSecondaryIndexes. Agrega una entrada para cada GSI, siguiendo la convención de nomenclatura de diseño de tabla única para las claves GSI:

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

    El campo sortKey es opcional para GSIs de solo clave hash.

    Este archivo de configuración es la única fuente de verdad leída por todos los consumidores:

    • Desarrollo localdev lee config.json y crea o actualiza la tabla local para que coincida con la lista de GSI
    • CDK — el constructo lee config.json en el momento de síntesis, por lo que los cambios de GSI se reflejan en el próximo cdk deploy
    • Terraform — el módulo lee config.json en el momento de plan/apply

    En cualquier proyecto TypeScript, importa las fábricas de entidades de tu paquete DynamoDB y úsalas directamente:

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

    El generador de DynamoDB crea infraestructura CDK o Terraform basada en tu iac seleccionado.

    El constructo CDK se crea en common/constructs. Ejemplo 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');
    }
    }

    Esto aprovisiona una tabla DynamoDB con:

    • pk (clave de partición) y sk (clave de ordenación), ambas de tipo String
    • Índices Secundarios Globales según se definen en config.json
    • Facturación bajo demanda (PAY_PER_REQUEST)
    • Cifrado KMS gestionado por el cliente con rotación automática de claves
    • Recuperación point-in-time habilitada
    • Protección contra eliminación habilitada
    • Nombre de tabla registrado en Runtime Config bajo el namespace dynamodb en AWS AppConfig

    Para permitir que las funciones Lambda accedan a la tabla de DynamoDB, otorga los permisos necesarios en tu infraestructura.

    Llama a grantReadWriteData en el constructo de la tabla. Esto otorga tanto los permisos de DynamoDB como de KMS requeridos por el rol de ejecución de 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);
    });

    La protección contra eliminación está habilitada por defecto para prevenir la eliminación accidental de la tabla.

    Deshabilitar la Protección contra Eliminación

    Sección titulada «Deshabilitar la Protección contra Eliminación»

    Deshabilítala para entornos donde se espera la eliminación de la tabla, como stacks de desarrollo o preview de corta duración.

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

    La tabla utiliza por defecto facturación bajo demanda (PAY_PER_REQUEST). Cambia a capacidad aprovisionada para cargas de trabajo predecibles de alto rendimiento.

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

    La recuperación point-in-time está habilitada por defecto, permitiéndote restaurar la tabla a cualquier punto en los últimos 35 días.

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

    La clave KMS utilizada para cifrar la tabla tiene la rotación automática de claves habilitada por defecto. Deshabilítala si tu política de seguridad gestiona la rotación externamente.

    Deshabilitar la Rotación de Clave de Cifrado

    Sección titulada «Deshabilitar la Rotación de Clave de Cifrado»
    packages/infra/src/stacks/application-stack.ts
    import { MyTable } from ':my-scope/common-constructs';
    const table = new MyTable(this, 'Table', {
    enableKeyRotation: false,
    });

    Usa el generador connection para integrar este proyecto con otros en tu workspace. Las siguientes conexiones involucran este proyecto:

    tRPC Amazon DynamoDB
    API tRPC a TypeScript DynamoDB Conecta una API tRPC a una tabla DynamoDB
    Smithy Amazon DynamoDB
    API Smithy a TypeScript DynamoDB Conecta una API Smithy a una tabla DynamoDB
    Strands Agents TypeScript Amazon DynamoDB
    TypeScript Agent a TypeScript DynamoDB Conecta un TypeScript Agent a una tabla DynamoDB
    Model Context Protocol Amazon DynamoDB
    Servidor MCP a TypeScript DynamoDB Conecta un Servidor MCP en TypeScript a una tabla DynamoDB