콘텐츠로 이동

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 테이블 구성

    제너레이터는 DynamoDB Local 인스턴스를 시작하고 테이블을 생성하는 dev 타겟을 구성합니다. 프로젝트의 dev 타겟을 사용하세요:

    Terminal window
    pnpm nx dev <project-name>

    이 명령은 자동으로 다음을 수행합니다:

    1. DynamoDB Local 이미지를 가져옵니다 (pull-image 타겟)
    2. 컨테이너를 시작합니다
    3. config.json에 정의된 인덱스로 로컬 테이블을 생성합니다

    생성된 프로젝트는 단일 DynamoDB 테이블에서 타입 안전한 엔티티 모델링을 위해 ElectroDB를 사용하며, 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"
    }
    ]
    }
    }

    sortKey 필드는 해시 키만 사용하는 GSI의 경우 선택 사항입니다.

    이 구성 파일은 모든 소비자가 읽는 단일 진실 공급원입니다:

    • 로컬 개발devconfig.json을 읽고 GSI 목록과 일치하도록 로컬 테이블을 생성하거나 업데이트합니다
    • CDK — 구성 요소가 synth 시점에 config.json을 읽으므로 GSI 변경 사항이 다음 cdk deploy에 반영됩니다
    • Terraform — 모듈이 plan/apply 시점에 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 네임스페이스 아래 Runtime Config에 등록된 테이블 이름

    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 테이블에 연결하기