21
Coder un système de migration pour NestJS avec mongoose
Prérequis:
- Un projet NestJS fonctionel
- Utiliser MongoDB et mongoose
Récemment, j'ai ressenti le besoin pressant de refactorer mon jeu discord.
C'est un projet en cours, loin d'être fini mais je ne supportais plus que les maisons soient appelées homes
au lieu de houses
.
Oh j'en entends déjà me dire : 'Change les labels affichés, c'est pareil!'.
Je me soucis de la consistance du nommage dans mes projets! Si les maisons sont des appartements, "c'est la porte ouverte à toutes les fenêtres".
Bref, j'enfile ma veste de chercheur et je me lance armé de mon meilleur google-fu.
Aujourd'hui, je vous présente le résultat de mon travail.
J'ai choisi d'utiliser la bibliothèque migrate
.
Un outil agnostique de tout type de base de données offrant une logique simple de script de migration et de retour en arrière.
De plus, le statut des migrations peut être stocké sous n'importe quel support (en base, un fichier json, ???).
Assez parlé de moi, laissez-moi vous guider.
Installation migrate
Installons ce coquin!
npm i --save migrate
On aura besoin de deux dossiers:
mkdir src/migrations
mkdir src/migrations-utils
Le premier contiendra nos scripts de migration et le second sera notre boîte à outils.
Commencons par le second!
Dans l'intro, nous avons vu que l'outil migrate
fait fi du type de nos bases de données.
Nous avons donc besoin d'un script pour nous connecter à mongodb:
import { MongoClient } from 'mongodb';
import { configs } from '../config/configuration';
const MONGO_URL = configs.mongoUrl;
export const getDb = async () => {
const client: any = await MongoClient.connect(MONGO_URL, { useUnifiedTopology: true });
return client.db();
};
Cool! Continuons!
Migrate est un outil écrit en javascript.
Et comme nous utilisons Typescript, la meilleur chose à faire est de créer un template déjà connecté à notre mongo.
import { getDb } from '../migrations-utils/db';
export const up = async () => {
const db = await getDb();
/*
La migration va ici.
*/
};
export const down = async () => {
const db = await getDb();
/*
Et ici, c'est pour le retour en arrière.
*/
};
J'ai rencontré quelques soucis avec ts-node/register
en utilisant migrate
en ligne de commande...
Ce petit script m'a sauvé la mise!
Vas-y! Maintenant! Ajoute-le!
// eslint-disable-next-line @typescript-eslint/no-var-requires
const tsNode = require('ts-node');
module.exports = tsNode.register;
Il est temps de mettre à jour le package.json
de notre projet afin d'avoir une jolie collection de script facile à utiliser!
Ajoutons cette ligne dans la section script du fichier package.json
"migrate:create": "migrate create --template-file ./src/migrations-utils/template.ts --migrations-dir=\"./src/migrations\" --compiler=\"ts:./src/migrations-utils/ts-compiler.js\"",
--template-file ./src/migrations-utils/template.ts
fourni le template, simple et efficace pour notre projet en typescript.
Le template est une façon rapide de créer la base de nos script de migration!
--migrations-dir=\"./src/migrations\"
Explique à migrate
où sont sensés être les scripts de migration.
Par défaut, c'est à la racine du projet...
--compiler=\"ts:./src/migrations-utils/ts-compiler.js\"
Explique à migrate
comment gérer les fichiers typescript.
Il suffit de lancer cette commande pour créer une migration vide en typescript dans le bon dossier!
npm run migrate:create -- <migration name>
EEEEEeeet deux lignes de plus dans le package.json
, toujours dans la section script!
"migrate:up": "migrate --migrations-dir=\"./src/migrations\" --compiler=\"ts:./src/migrations-utils/ts-compiler.js\" up",
"migrate:down": "migrate --migrations-dir=\"./src/migrations\" --compiler=\"ts:./src/migrations-utils/ts-compiler.js\" down"
Pas de nouvelle option ici, tout est expliqué au-dessus mais comme je suis sympa voila un petit rappel.
--migrations-dir=\"./src/migrations\"
Explique à migrate
où sont nos scripts de migration...
--compiler=\"ts:./src/migrations-utils/ts-compiler.js\"
Explique à migrate
comment gérer les fichiers typescript...
On peut maintenant exécuter le script npm run migrate:up
pour les migrations et le script npm run migrate:down
pour revenir en arrière.
Migrate va stocker l'état des migrations dans un fichier à la racine du projet.
Ce fichier est: migrate.json
.
Il ressemble à ça:
{
"lastRun": "1605197159478-test.ts",
"migrations": [
{
"title": "1605197159478-test.ts",
"timestamp": 1605197181474
}
]
}
NE PAS COMMITER migrate.json
Je serais heureux de répondre aux questions en commentaires.
Si cette article t'as plu, n'hésite pas à me rejoindre sur le discord Webeleon!
☎️Discord webeleon
Tu peux aussi me contacter par mail si tu cherches un freelance sympa et efficace 💰
✉️Email moi!
Et comme je suis partageur, tu trouveras les sources sur github!
🎁Récupère le code sur github!
21