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.
Cách sử dụng
Phần tiêu đề “Cách sử dụng”Tạo một dự án TypeScript DynamoDB
Phần tiêu đề “Tạo một dự án TypeScript DynamoDB”- Cài đặt Nx Console VSCode Plugin nếu bạn chưa cài đặt
- Mở Nx Console trong VSCode
- Nhấp
Generate (UI)trong phần "Common Nx Commands" - Tìm kiếm
@aws/nx-plugin - ts#dynamodb - Điền các tham số bắt buộc
- Nhấp
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#dynamodbBạn cũng có thể thực hiện chạy thử để xem những tệp nào sẽ bị thay đổi
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-runTùy chọn
Phần tiêu đề “Tùy chọn”| 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. |
Kết quả của Generator
Phần tiêu đề “Kết quả của Generator”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
Cơ sở hạ tầng
Phần tiêu đề “Cơ sở hạ tầng”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/terraform
Thư mụcsrc
Thư mụcapp/ Terraform modules cho infrastructure cụ thể của một dự án/generator
- …
Thư mụccore/ Modules chung được tái sử dụng bởi các modules trong
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
Thư mụcpackages/common/terraform/src
Thư mụcapp
Thư mụcdynamodb
Thư mục<name>
- <name>.tf Module cụ thể cho bảng của bạn
Thư mụccore
Thư mụcdynamodb
- dynamodb.tf Module DynamoDB chung
Phát triển cục bộ
Phần tiêu đề “Phát triển cục bộ”Khởi động DynamoDB cục bộ
Phần tiêu đề “Khởi động DynamoDB cục bộ”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:
pnpm nx dev <project-name>yarn nx dev <project-name>npx nx dev <project-name>bunx nx dev <project-name>Điều này tự động:
- Kéo image DynamoDB Local (target
pull-image) - Khởi động một container
- Tạo một bảng local với các index được định nghĩa trong
config.json
Mô hình hóa dữ liệu
Phần tiêu đề “Mô hình hóa dữ liệu”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ể:
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.
Sử dụng DynamoDB Client
Phần tiêu đề “Sử dụng DynamoDB Client”Tệp src/client.ts được tạo xuất hai tiện ích chính:
getDynamoDBClient()— trả về một singletonDynamoDBClientđược lưu trong bộ nhớ cache. KhiLOCAL_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. KhiLOCAL_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ườngRUNTIME_CONFIG_APP_IDvà lưu vào bộ nhớ cache cho các lần gọi tiếp theo.
Dừng DynamoDB cục bộ
Phần tiêu đề “Dừng DynamoDB cục bộ”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.
Thêm/Xóa Global Secondary Indexes
Phần tiêu đề “Thêm/Xóa Global Secondary Indexes”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:
{ ... "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 development —
devđọcconfig.jsonvà 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.jsontại thời điểm synth, do đó các thay đổi GSI sẽ được phản ánh trong lầncdk deploytiếp theo - Terraform — module đọc
config.jsontại thời điểm plan/apply
Một GSI cho mỗi Deployment
Phần tiêu đề “Một GSI cho mỗi Deployment”Kết nối đến bảng
Phần tiêu đề “Kết nối đến bảng”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();Triển khai bảng của bạn
Phần tiêu đề “Triển khai bảng của bạn”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:
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ểuString- 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
dynamodbtrong AWS AppConfig
Module Terraform được tạo trong common/terraform. Ví dụ sử dụng:
module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-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ểuString- 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
Cấp quyền truy cập
Phần tiêu đề “Cấp quyền truy cập”Để 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:
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);});Cấp quyền cho vai trò thực thi Lambda để truy cập bảng DynamoDB và khóa mã hóa KMS của nó:
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] }, ] })}Bảo vệ xóa
Phần tiêu đề “Bảo vệ xóa”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 bảo vệ xóa
Phần tiêu đề “Tắt bảo vệ xóa”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.
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}Chế độ thanh toán
Phần tiêu đề “Chế độ thanh toán”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.
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"}Khôi phục theo thời điểm
Phần tiêu đề “Khôi phục theo thời điểm”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.
Tắt khôi phục theo thời điểm
Phần tiêu đề “Tắt khôi phục theo thời điểm”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}Xoay khóa mã hóa
Phần tiêu đề “Xoay khóa mã hóa”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.
Tắt xoay khóa mã hóa
Phần tiêu đề “Tắt xoay khóa mã hóa”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}Kết nối
Phần tiêu đề “Kết nối”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: