TypeScript DynamoDB
Ce générateur crée un nouveau projet TypeScript DynamoDB basé sur Amazon DynamoDB, utilisant ElectroDB pour la modélisation d’entités avec sécurité de type. Il génère le code d’application et l’infrastructure nécessaires pour provisionner et gérer une table DynamoDB en utilisant AWS CDK ou Terraform, avec prise en charge de la conception à table unique et développement local intégré via DynamoDB Local.
Utilisation
Section intitulée « Utilisation »Générer un projet TypeScript DynamoDB
Section intitulée « Générer un projet TypeScript DynamoDB »- Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
- Ouvrez la console Nx dans VSCode
- Cliquez sur
Generate (UI)dans la section "Common Nx Commands" - Recherchez
@aws/nx-plugin - ts#dynamodb - Remplissez les paramètres requis
- Cliquez sur
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#dynamodbVous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
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| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
| name Requis | string | - | Nom du projet DynamoDB à générer |
| directory | string | packages | Le répertoire dans lequel stocker le projet. |
| subDirectory | string | - | Le sous-répertoire dans lequel le projet est placé. Par défaut, il s'agit du nom du projet. |
| framework | electrodb | electrodb | Le framework à utiliser pour les entités DynamoDB. |
| tableName | string | - | Le nom de la table DynamoDB. Généré automatiquement si non spécifié. |
| infra | dynamodb | none | dynamodb | Infrastructure à provisionner pour la table DynamoDB. |
| iac | inherit | cdk | terraform | inherit | Le fournisseur IaC préféré. Par défaut, celui-ci est hérité de votre sélection initiale. |
| preferInstallDependencies | boolean | true | Indique s'il faut privilégier l'installation des dépendances après l'exécution du générateur. Définir sur false pour différer l'installation lors de l'exécution de plusieurs générateurs en lot (une installation s'exécute quand même si nécessaire pour que les générateurs suivants puissent calculer le graphe de projet Nx) ; installer une seule fois à la fin. |
Sortie du générateur
Section intitulée « Sortie du générateur »Le générateur crée la structure de projet suivante dans le répertoire <directory>/<name> :
Répertoiresrc
- index.ts Point d’entrée du projet et exports
- client.ts Singleton du client DynamoDB et résolution du nom de table
Répertoireentities
- example.ts Exemple de définition d’entité ElectroDB
- index.ts Exports des entités
- config.json Configuration de la table incluant les définitions GSI et les paramètres de développement local
- project.json Configuration du projet et cibles de build
Les scripts de développement local sont partagés entre tous les projets DynamoDB (TypeScript et Python) et générés une fois dans :
Répertoirepackages/common/scripts/src/dynamodb
- create-local-table.ts Crée la table DynamoDB dans l’instance DynamoDB Local locale
- pull-image.ts Télécharge l’image DynamoDB Local
- start-container.ts Démarre le conteneur DynamoDB Local
Infrastructure
Section intitulée « Infrastructure »Ce générateur fournit de l’infrastructure as code basée sur votre iacProvider choisi. Il créera un projet dans packages/common qui inclut les constructions CDK ou modules Terraform pertinents.
Le projet commun d’infrastructure as code est structuré comme suit :
Répertoirepackages/common/constructs
Répertoiresrc
Répertoireapp/ Constructions pour l’infrastructure spécifique à un projet/générateur
- …
Répertoirecore/ Constructions génériques réutilisées par celles dans
app- …
- index.ts Point d’entrée exportant les constructions depuis
app
- project.json Cibles de build et configuration du projet
Répertoirepackages/common/terraform
Répertoiresrc
Répertoireapp/ Modules Terraform pour l’infrastructure spécifique à un projet/générateur
- …
Répertoirecore/ Modules génériques réutilisés par ceux dans
app- …
- project.json Cibles de build et configuration du projet
Répertoirepackages/common/constructs/src
Répertoireapp
Répertoiredynamodb
- <name>.ts Infrastructure spécifique à votre table
Répertoirecore
- dynamodb.ts Construct générique de table DynamoDB
Répertoirepackages/common/terraform/src
Répertoireapp
Répertoiredynamodb
Répertoire<name>
- <name>.tf Module spécifique à votre table
Répertoirecore
Répertoiredynamodb
- dynamodb.tf Module DynamoDB générique
Développement local
Section intitulée « Développement local »Démarrer DynamoDB Local
Section intitulée « Démarrer DynamoDB Local »Le générateur configure une cible dev qui démarre une instance DynamoDB Local et crée la table. Utilisez la cible dev du projet :
pnpm nx dev <project-name>yarn nx dev <project-name>npx nx dev <project-name>bunx nx dev <project-name>Cela effectue automatiquement :
- Télécharge l’image DynamoDB Local (cible
pull-image) - Démarre un conteneur
- Crée une table locale avec les index définis dans
config.json
Modélisation des données
Section intitulée « Modélisation des données »Le projet généré utilise ElectroDB pour la modélisation d’entités avec sécurité de type sur une seule table DynamoDB, en suivant la conception à table unique de DynamoDB. Ajoutez ou mettez à jour les fichiers d’entités sous src/entities/, en utilisant l’exemple d’entité généré comme point de départ.
Exemple de définition d’entité :
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() }, );Pour plus de détails, consultez la documentation des entités ElectroDB.
Utilisation du client DynamoDB
Section intitulée « Utilisation du client DynamoDB »Le fichier généré src/client.ts exporte deux utilitaires clés :
getDynamoDBClient()— retourne un singletonDynamoDBClienten cache. LorsqueLOCAL_DEV=true, se connecte à l’instance DynamoDB Local locale ; sinon crée un client AWS utilisant la chaîne d’identification par défaut.resolveTableName()— retourne le nom de la table DynamoDB. LorsqueLOCAL_DEV=true, retourne la constante du nom de table locale ; sinon récupère le nom depuis AWS AppConfig en utilisant la variable d’environnementRUNTIME_CONFIG_APP_IDet le met en cache pour les appels suivants.
Arrêter DynamoDB Local
Section intitulée « Arrêter DynamoDB Local »L’arrêt de dev (par exemple avec Ctrl+C) supprime automatiquement le conteneur DynamoDB Local, mais préserve le volume nommé afin que vos données persistent entre les redémarrages.
Ajout/Suppression d’index secondaires globaux
Section intitulée « Ajout/Suppression d’index secondaires globaux »Les GSI sont définis dans config.json à la racine du projet sous la clé tableConfig.globalSecondaryIndexes. Ajoutez une entrée pour chaque GSI, en suivant la convention de nommage de conception à table unique pour les clés GSI :
{ ... "tableConfig": { "globalSecondaryIndexes": [ { "indexName": "gsi1pk-gsi1sk-index", "partitionKey": "gsi1pk", "sortKey": "gsi1sk" }, { "indexName": "gsi2pk-gsi2sk-index", "partitionKey": "gsi2pk", "sortKey": "gsi2sk" } ] }}Le champ sortKey est optionnel pour les GSI avec clé de hachage uniquement.
Ce fichier de configuration est la source unique de vérité lue par tous les consommateurs :
- Développement local —
devlitconfig.jsonet crée ou met à jour la table locale pour correspondre à la liste des GSI - CDK — le construct lit
config.jsonau moment de la synthèse, donc les modifications de GSI sont reflétées lors du prochaincdk deploy - Terraform — le module lit
config.jsonau moment du plan/apply
Un GSI par Déploiement
Section intitulée « Un GSI par Déploiement »Connexion à la table
Section intitulée « Connexion à la table »Dans n’importe quel projet TypeScript, importez les factories d’entités depuis votre package DynamoDB et utilisez-les directement :
import { createExampleEntity } from ':my-scope/my-table';
const entity = await createExampleEntity();const result = await entity.query.primary({ id: '123' }).go();Déploiement de votre table
Section intitulée « Déploiement de votre table »Le générateur DynamoDB crée une infrastructure CDK ou Terraform en fonction de votre iac sélectionné.
Le construct CDK est créé dans common/constructs. Exemple d’utilisation :
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'); }}Cela provisionne une table DynamoDB avec :
pk(clé de partition) etsk(clé de tri), toutes deux de typeString- Des index secondaires globaux tels que définis dans
config.json - Une facturation à la demande (
PAY_PER_REQUEST) - Un chiffrement KMS géré par le client avec rotation automatique des clés
- La récupération à un instant donné activée
- La protection contre la suppression activée
- Le nom de la table enregistré dans Runtime Config sous l’espace de noms
dynamodbdans AWS AppConfig
Le module Terraform est créé dans common/terraform. Exemple d’utilisation :
module "my_table" { source = "../../common/terraform/src/app/dynamodb/my-table"}Cela provisionne une table DynamoDB avec :
pk(clé de partition) etsk(clé de tri), toutes deux de typeString- Des index secondaires globaux tels que définis dans
config.json - Une facturation à la demande (
PAY_PER_REQUEST) - Un chiffrement KMS géré par le client avec rotation automatique des clés
- La récupération à un instant donné activée
- La protection contre la suppression activée
- Le nom de la table enregistré dans Runtime Config
Accorder l’accès
Section intitulée « Accorder l’accès »Pour permettre aux fonctions Lambda d’accéder à la table DynamoDB, accordez les permissions nécessaires dans votre infrastructure.
Appelez grantReadWriteData sur le construct de la table. Cela accorde à la fois les permissions DynamoDB et KMS requises par le rôle d’exécution 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);});Accordez au rôle d’exécution Lambda la permission d’accéder à la table DynamoDB et à sa clé de chiffrement 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] }, ] })}Protection contre la suppression
Section intitulée « Protection contre la suppression »La protection contre la suppression est activée par défaut pour empêcher la suppression accidentelle de la table.
Désactiver la protection contre la suppression
Section intitulée « Désactiver la protection contre la suppression »Désactivez-la pour les environnements où la suppression de la table est attendue, tels que les stacks de développement ou de prévisualisation éphémères.
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}Mode de facturation
Section intitulée « Mode de facturation »La table utilise par défaut la facturation à la demande (PAY_PER_REQUEST). Passez à la capacité provisionnée pour des charges de travail prévisibles et à haut débit.
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"}Récupération à un instant donné
Section intitulée « Récupération à un instant donné »La récupération à un instant donné est activée par défaut, vous permettant de restaurer la table à n’importe quel moment des 35 derniers jours.
Désactiver la récupération à un instant donné
Section intitulée « Désactiver la récupération à un instant donné »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}Rotation des clés de chiffrement
Section intitulée « Rotation des clés de chiffrement »La clé KMS utilisée pour chiffrer la table a la rotation automatique des clés activée par défaut. Désactivez-la si votre politique de sécurité gère la rotation en externe.
Désactiver la rotation des clés de chiffrement
Section intitulée « Désactiver la rotation des clés de chiffrement »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}Connexions
Section intitulée « Connexions »Utilisez le générateur connection pour intégrer ce projet avec d’autres dans votre espace de travail. Les connexions suivantes impliquent ce projet :