TypeScript DynamoDB
이 생성기는 Amazon DynamoDB를 기반으로 하는 새로운 TypeScript DynamoDB 프로젝트를 생성하며, 타입 안전한 엔티티 모델링을 위해 ElectroDB를 사용합니다. AWS CDK 또는 Terraform을 사용하여 DynamoDB 테이블을 프로비저닝하고 관리하는 데 필요한 애플리케이션 코드와 인프라를 생성하며, 단일 테이블 설계 지원과 DynamoDB Local을 통한 내장 로컬 개발 환경을 제공합니다.
사용법
섹션 제목: “사용법”TypeScript DynamoDB 프로젝트 생성
섹션 제목: “TypeScript DynamoDB 프로젝트 생성”- 설치 Nx Console VSCode Plugin 아직 설치하지 않았다면
- VSCode에서 Nx 콘솔 열기
- 클릭
Generate (UI)"Common Nx Commands" 섹션에서 - 검색
@aws/nx-plugin - ts#dynamodb - 필수 매개변수 입력
- 클릭
Generate
pnpm nx g @aws/nx-plugin:ts#dynamodbyarn nx g @aws/nx-plugin:ts#dynamodbnpx nx g @aws/nx-plugin:ts#dynamodbbunx nx g @aws/nx-plugin:ts#dynamodb어떤 파일이 변경될지 확인하기 위해 드라이 런을 수행할 수도 있습니다
pnpm nx g @aws/nx-plugin:ts#dynamodb --dry-runyarn nx g @aws/nx-plugin:ts#dynamodb --dry-runnpx nx g @aws/nx-plugin:ts#dynamodb --dry-runbunx nx g @aws/nx-plugin:ts#dynamodb --dry-run| 매개변수 | 타입 | 기본값 | 설명 |
|---|---|---|---|
| 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/terraform
디렉터리src
디렉터리app/ 특정 프로젝트/생성기 전용 Terraform 모듈
- …
디렉터리core/
app내 모듈에서 재사용되는 일반적 모듈- …
- project.json 프로젝트 빌드 대상 및 구성
디렉터리packages/common/constructs/src
디렉터리app
디렉터리dynamodb
- <name>.ts 테이블에 특화된 인프라
디렉터리core
- dynamodb.ts 범용 DynamoDB 테이블 구성
디렉터리packages/common/terraform/src
디렉터리app
디렉터리dynamodb
디렉터리<name>
- <name>.tf 테이블에 특화된 모듈
디렉터리core
디렉터리dynamodb
- dynamodb.tf 범용 DynamoDB 모듈
로컬 개발
섹션 제목: “로컬 개발”로컬 DynamoDB 시작
섹션 제목: “로컬 DynamoDB 시작”제너레이터는 DynamoDB Local 인스턴스를 시작하고 테이블을 생성하는 dev 타겟을 구성합니다. 프로젝트의 dev 타겟을 사용하세요:
pnpm nx dev <project-name>yarn nx dev <project-name>npx nx dev <project-name>bunx nx dev <project-name>이 명령은 자동으로 다음을 수행합니다:
- DynamoDB Local 이미지를 가져옵니다 (
pull-image타겟) - 컨테이너를 시작합니다
config.json에 정의된 인덱스로 로컬 테이블을 생성합니다
데이터 모델링
섹션 제목: “데이터 모델링”생성된 프로젝트는 단일 DynamoDB 테이블에서 타입 안전한 엔티티 모델링을 위해 ElectroDB를 사용하며, DynamoDB의 단일 테이블 설계를 따릅니다. 생성된 예제 엔티티를 시작점으로 사용하여 src/entities/ 아래에 엔티티 파일을 추가하거나 업데이트하세요.
엔티티 정의 예제:
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 엔티티 문서를 참조하세요.
DynamoDB 클라이언트 사용
섹션 제목: “DynamoDB 클라이언트 사용”생성된 src/client.ts는 두 가지 주요 유틸리티를 내보냅니다:
getDynamoDBClient()— 캐시된 싱글톤DynamoDBClient를 반환합니다.LOCAL_DEV=true일 때는 로컬 DynamoDB Local 인스턴스에 연결하고, 그렇지 않으면 기본 자격 증명 체인을 사용하여 AWS 클라이언트를 생성합니다.resolveTableName()— DynamoDB 테이블 이름을 반환합니다.LOCAL_DEV=true일 때는 로컬 테이블 이름 상수를 반환하고, 그렇지 않으면RUNTIME_CONFIG_APP_ID환경 변수를 사용하여 AWS AppConfig에서 이름을 가져와 후속 호출을 위해 캐시합니다.
로컬 DynamoDB 중지
섹션 제목: “로컬 DynamoDB 중지”dev를 중지하면 (예: Ctrl+C 사용) DynamoDB Local 컨테이너가 자동으로 제거되지만, 명명된 볼륨은 보존되므로 재시작 시에도 데이터가 유지됩니다.
글로벌 보조 인덱스 추가/제거
섹션 제목: “글로벌 보조 인덱스 추가/제거”GSI는 프로젝트 루트의 config.json에서 tableConfig.globalSecondaryIndexes 키 아래에 정의됩니다. 각 GSI에 대해 항목을 추가하고, GSI 키에 대한 단일 테이블 설계 명명 규칙을 따르세요:
{ ... "tableConfig": { "globalSecondaryIndexes": [ { "indexName": "gsi1pk-gsi1sk-index", "partitionKey": "gsi1pk", "sortKey": "gsi1sk" }, { "indexName": "gsi2pk-gsi2sk-index", "partitionKey": "gsi2pk", "sortKey": "gsi2sk" } ] }}sortKey 필드는 해시 키만 사용하는 GSI의 경우 선택 사항입니다.
이 구성 파일은 모든 소비자가 읽는 단일 진실 공급원입니다:
- 로컬 개발 —
dev가config.json을 읽고 GSI 목록과 일치하도록 로컬 테이블을 생성하거나 업데이트합니다 - CDK — 구성 요소가 synth 시점에
config.json을 읽으므로 GSI 변경 사항이 다음cdk deploy에 반영됩니다 - Terraform — 모듈이 plan/apply 시점에
config.json을 읽습니다
배포당 하나의 GSI
섹션 제목: “배포당 하나의 GSI”테이블 연결
섹션 제목: “테이블 연결”모든 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에 생성됩니다. 사용 예시:
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에 등록된 테이블 이름
Terraform 모듈은 common/terraform에 생성됩니다. 사용 예시:
module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table"}다음과 같은 DynamoDB 테이블을 프로비저닝합니다:
pk(파티션 키)와sk(정렬 키), 둘 다String타입config.json에 정의된 글로벌 보조 인덱스- 온디맨드 (
PAY_PER_REQUEST) 요금제 - 자동 키 로테이션이 활성화된 고객 관리형 KMS 암호화
- 특정 시점 복구 활성화
- 삭제 보호 활성화
- Runtime Config에 등록된 테이블 이름
액세스 권한 부여
섹션 제목: “액세스 권한 부여”Lambda 함수가 DynamoDB 테이블에 액세스할 수 있도록 하려면 인프라에서 필요한 권한을 부여하세요.
테이블 구성에서 grantReadWriteData를 호출하세요. 이는 Lambda 실행 역할에 필요한 DynamoDB 및 KMS 권한을 모두 부여합니다:
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);});Lambda 실행 역할에 DynamoDB 테이블 및 KMS 암호화 키에 액세스할 수 있는 권한을 부여하세요:
module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table"}
resource "aws_iam_role_policy" "dynamodb_access" { role = module.my_api.lambda_role_name
policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem", ] Resource = [ module.my_table.table_arn, "${module.my_table.table_arn}/index/*", ] }, { Effect = "Allow" Action = [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ] Resource = [module.my_table.kms_key_arn] }, ] })}삭제 보호
섹션 제목: “삭제 보호”실수로 테이블이 삭제되는 것을 방지하기 위해 삭제 보호가 기본적으로 활성화되어 있습니다.
삭제 보호 비활성화
섹션 제목: “삭제 보호 비활성화”단기 개발 또는 프리뷰 스택과 같이 테이블 삭제가 예상되는 환경에서는 비활성화하세요.
import { MyTable } from ':my-scope/common-constructs';
const table = new MyTable(this, 'Table', { deletionProtection: false,});module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table" deletion_protection_enabled = false}요금제 모드
섹션 제목: “요금제 모드”테이블은 기본적으로 온디맨드 (PAY_PER_REQUEST) 요금제를 사용합니다. 예측 가능한 고처리량 워크로드의 경우 프로비저닝된 용량으로 전환하세요.
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,});module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table" billing_mode = "PROVISIONED"}특정 시점 복구
섹션 제목: “특정 시점 복구”특정 시점 복구는 기본적으로 활성화되어 있으며, 지난 35일 중 임의의 시점으로 테이블을 복원할 수 있습니다.
특정 시점 복구 비활성화
섹션 제목: “특정 시점 복구 비활성화”import { MyTable } from ':my-scope/common-constructs';
const table = new MyTable(this, 'Table', { pointInTimeRecoverySpecification: { pointInTimeRecoveryEnabled: false },});module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table" point_in_time_recovery_enabled = false}암호화 키 로테이션
섹션 제목: “암호화 키 로테이션”테이블을 암호화하는 데 사용되는 KMS 키는 기본적으로 자동 키 로테이션이 활성화되어 있습니다. 보안 정책에서 외부적으로 로테이션을 관리하는 경우 비활성화하세요.
암호화 키 로테이션 비활성화
섹션 제목: “암호화 키 로테이션 비활성화”import { MyTable } from ':my-scope/common-constructs';
const table = new MyTable(this, 'Table', { enableKeyRotation: false,});module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table" enable_key_rotation = false}connection 생성기를 사용하여 이 프로젝트를 워크스페이스의 다른 프로젝트와 통합할 수 있습니다. 다음은 이 프로젝트와 관련된 연결입니다: