Connexion dynamique à plusieurs bases de données avec NestJS

La documentation officielle de NestJS explique très clairement comment se connecter à plusieurs bases de données en utilisant une configuration statique.

L’un de nos clients a un cas d’usage différent et souhaite que son application puisse se connecter à plusieurs bases de données chacune étant dédiée à un pays. Il veut pouvoir ajouter et supprimer des bases de données dynamiquement, sans avoir à modifier le code source.

Voici les principales différences entre ces deux modèles :

 StatiqueDynamique
Structure de la baseIdentique ou différenteDoit être identique
Ajouter/supprimer une baseModification du codeModificaton de la configuration et redémarrage de l’application

Mettre en place la configuration dynamique

Voici le fichier.env tel qu’on souhaiterait l’utiliser :

DATABASE_SYSTEM_IDS est une liste séparée par des virgules d’identifiants système définis arbitrairement et qui représentent chacune des bases de données à laquelle on souhaite se connecter. Pour chaque identifiant système on définit un jeu de variables nommées DB_xx_*xx prend la valeur de cet identifiant.

Ci-dessous la classe de configuration qui nous permet de gérer ce genre de configuration (fichier src/common/config/orm.config.ts) :

Voici comment on génère dynamiquement une configuration TypeORM pour chaque base de données  (fichier src/home/jnesis/www/wp.module.ts) :

Notez que chacune de ces configurations TypeORM se voit assigner le nom database-xxxx est l’identifiant système.

Mettre en place l'injection de dépendance dynamique

Maintenant que notre configuration est dynamique, nous avons besoin de nous connecter à une base de données en particulier en utilisant son identifiant système. L’injection de dépendance standard (à travers @InjectEntityManager , @InjectRepository, etc…) ne peut pas être utilisée car elle requiert de connaître la base de données à laquelle on souhaite se connecter au moment de la compilation.

Pour pouvoir sélectionner dynamiquement une base de données pendant l’exécution de l’application, il nous faut utiliser la fonctionnalité module reference de NestJS. De cette manière il est possible d’instancier un EntityManager depuis son nom de configuration TypeORM database-xx (méthode loadEntityManager dans le fichier src/car-manufacturers/car-manufacturers.service.ts) :

Projet de démonstration

Vous trouverez un exemple complet et fonctionnel ici sur Github.

La limitation de structure identique

En réalité nous pourrions avoir des structures différentes même avec des bases de données dynamiques. Cela nécessite de définir la forme de chaque base en indiquant le jeu d’entitées qu’elle va utiliser.

Par exemple nous pourrions ajouter un paramètre au fichier .env :

A partir de là il nous suffit de charger les entitées dynamiquement en se basant sur le nom de la structure en tant que suffixe (fichier src/common/config/orm.config.ts) :

Il faudra alors définir les entités pour chaque structure et elle peuvent être complètement différentes :

  • StructureA: car-manufacturer.structureA.entity.ts
  • StructureB: brand.structureB.entity.ts, address.structureB.entity.ts

Évidemment les requêtes vont être différentes d’une structure à l’autre, cela nécessitera donc des ajouts de conditions et branchements dans le code métier.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Jnesis
Résumé de la politique de confidentialité

Ce site utilise des cookies afin que nous puissions vous fournir la meilleure expérience utilisateur possible. Les informations sur les cookies sont stockées dans votre navigateur et remplissent des fonctions telles que vous reconnaître lorsque vous revenez sur notre site Web et aider notre équipe à comprendre les sections du site que vous trouvez les plus intéressantes et utiles.