Architecture projet
Maintenant que les bases de Node et de la gestion d'API sont acquises il va être temps de structurer un peu mieux notre projet.
Exporter un module
La première chose que nous pourrions imaginer serait de découper notre projet en plusieurs fichiers que l'on placerait dans un dossier src
.
Nosu avons appris la notion de module via les packages que nous installions. Ensuite nous importions ces modules dans notre code via la commande require
ou import
selon que vous êtes en ES ou CommonJS. Nous pouvons faire la même chose avec nos propres fichiers.
Je voudrais par exempler isoler le contrôle et l'appel à prisma
dans un fichier users.controller.js
et l'exporter pour pouvoir l'utiliser dans d'autres fichiers. Comme nos fichiers sont en typescript nous allons préferer la syntaxe import
mais nous pourrions aussi utiliser require
.
import { PrismaClient } from '@prisma/client';
import { Request, Response } from 'express';
const prisma = new PrismaClient();
export const getUsersController = async (req: Request, res: Response) => {
const users = await prisma.user.findMany();
return res.status(200).send(users);
};
Je peux désormais importer cette fonction dans mon fichier index.ts
et l'utiliser.
import { getUsersController } from './users.controller';
app.get('/users', getUsersController);
Structurer l'application
Maintenant que nous savons exporter des éléments de notre code NodeJS nous allons essayer de suivre une architecture plus conventionnelle pour notre projet.
Routes
Les routes seront les points d'entrée de notre API. Elles seront définies dans un fichier *.route.js
et seront appelées dans l'index. Elles pourront appeler des middlewares et des controllers pour répondre aux requêtes HTTP.
Middlewares
Les middlewares seront des fonctions qui seront appelées avant les routes. Elles pourront vérifier des informations, modifier des données ou encore appeler des fonctions externes. Elles seront appelées dans les routes via la méthode use
de express
. Elles seront définies dans un fichier *.middleware.js
.
Controllers
Les controllers seront les fonctions qui contiendront la logique métier de notre application. Ils seront appelés par les routes et pourront appeler les modèles pour intéragir avec la base de donnée. Ils seront définis dans un fichier *.controller.js
.
Modeles
Les modèles seront les fonctions qui permettront d'intéragir avec la base de donnée. Ils seront appelés par les controllers et pourront faire des requêtes à la base de donnée. Ils seront définis dans un fichier *.model.js
.
Comme nous utilisons
prisma
qui sert de modèle nous n'aurons pas besoin de créer de modèle pour l'instant.
Exemple
project-root/
├── src
│ ├── common
│ │ └── *.middleware.js
├───├── *
│ │ ├── *.middleware.js
│ │ ├── *.model.js (si nécessaire)
│ │ ├── *.controller.js
│ │ └── *.route.js
│ └─── index.js
├── package.json
├── .env
├── prisma
├── node_modules
├── tsconfig.json
Chaque partie de notre projet sera désormais proprement découpée. L'index fera appel aux routes, qui feront appels aux controllers (et aux middlewares si nécessaires) puis ces controllers appelleront les modèles qui intéragiront avec la base de donnée.