Framework tsoa
Jusqu'à présent, nous avons utilisé Basic Express pour construire notre API REST. Vous avez peut-être remarqué qu'il y a beaucoup de répétitions et que nous réinventons parfois la roue !
C'est pourquoi il existe un certain nombre de Frameworks qui mettent en place une structure de projet, un schéma de routage normalisé, des protocoles de sécurité, etc. C'est parfois une bonne chose, mais c'est aussi parfois trop restrictif !
Ce qui nous manque pour l'instant, c'est une façon harmonisée de structurer notre projet et nos appels REST. De plus, il serait formidable de pouvoir documenter notre API afin que les gens puissent l'utiliser !
Il existe bien sûr des frameworks complets que nous n'abordons pas dans notre cours : NestJS, NextJS, Nuxt, Symfony, Ruby On Rails, Java Spring, etc.
Pour ce cours, nous voulons être aussi neutres que possible par rapport à un Framework, tout en introduisant juste ce qu'il faut pour structurer notre projet. Pourquoi ?
Pour exposer plus proprement les principes et les choix de conception
Pour nous donner la marge de manœuvre nécessaire pour mettre en œuvre nous-mêmes certaines techniques
Pour nous permettre d'apprendre et d'apprécier ce qui se passe dans les coulisses d'un Framework moderne.
Nous utiliserons tsoa
pour structurer notre projet. Je trouve qu'il ajoute une quantité suffisante de structure à notre projet, tout en laissant assez de flexibilité pour faire ce que nous voulons. tsoa
est opinionated. On est obligé de structurer notre code à leurs normes pour que la documentation soit cohérente.
Orienté objet : on précise un objet par endpoint avec des fonctions dedans pour les opérations type CRUD - cet objet est un
Controller
dans le pattern MVC.Décorateurs : on utilise les décorateurs de typescript pour apporter de l'information concernant les routes, paramètres etc
Routing est opaque : au lieu de créer des routes nous même, on laisse
tsoa
construire notre API dans Express selon les décorateurs. C'est le seul point que je n'aime pas, mais l'avantage d'avoir une documentation cohérente fait équilibrer ce désavantage.
Installer tsoa
tsoa
Installer tsoa
(TypeScript Open Api) :
Dans tsconfig.json
il faut activer l'usage des décorateurs TypeScript :
Créer un controller
On transforme nos routes /user
sur le format précisé par tsoa
(dans le fichier src/controllers/UserController.ts
) :
tsoa
compile tous nos contrôleurs et les transforme en routes Express pour nous. Le contrôleur ci-dessus, grâce à ses annotations, créera ce qui suit :
GET /user
PUT /user
GET /user/:userId
PATCH /user/:userId
DELETE /user/:userId
Cette compilation se fait dans une étape séparée que nous configurerons dans la section suivante. Mais les annotations @Route
, @Get
, @Query
, etc. sont utilisées par le processus de compilation pour :
écrire automatiquement les routes Express pour nous
ajouter une validation automatique aux données entrantes
éventuellement écrire automatiquement notre documentation à partir des commentaires !
Notre contrôleur remplace le fichier routes/user.route.ts
que nous avons écrit dans un chapitre précédent. Vous pouvez le supprimer.
Configurer tsoa
Ensuite, nous allons créer un fichier de configuration pour tsoa
à ./tsoa.json
:
On précise
spec.outputDirectory
pour le fichier avec notre documentation. On le met dans le dossier public qui sera servi comme fichier staticOn précise
routes.routesDir
pour la destination du routeur Express qui est automatiquement générée partsoa
Enfin, on duplique les
compilerOptions
du fichiertsconfig.json
pour que nos raccourcis soient pris en compte.
tsoa
va construire un set de routes automatiquement, ainsi qu'un fichier swagger contenant toute la documentation de notre API. Pour cela, il faudrait lancer un script :
Essayons :
Consultez les nouveaux fichiers créés. On verra de la trace de routes définies dans notre UserController.ts
Ensuite, il faut inclure ce code dans notre server.ts
:
Validation
Essayez d'envoyer des données non valides à votre API. Ceci est rejeté par notre API car tsoa
valide automatiquement les données en se basant sur les types que nous spécifions dans les annotations. C'est très intéressant !
Cependant, nous pouvons souhaiter modifier notre gestionnaire d'erreur pour envoyer des informations utiles à l'utilisateur.
Si vous répétez la demande, vous obtiendrez des informations utiles sur ce qui n'a pas fonctionné.
Automatiser la recompilation de tsoa
Vous avez sûrement remarqué qu'à chaque modification, on est obligé de recompiler les routes de tsoa
. On peut automatiser tout cela en ajoutant une configuration pour nodemon
dans nodemon.json
:
Ici, on lance systématiquement la recompilation des routes avant de lancer le serveur, tout en ignorant le fichier routes.ts
qui est le fichier généré par tsoa
.
On peut simplifier alors notre package.json
, car nodemon.json
est automatiquement lu par nodemon
lors de son exécution :
Faire le menage
Nous avons maintenant remplacé notre ancien user.route.ts
par un contrôleur qui est automatiquement compilé dans les routes Express. Nous pouvons donc supprimer cet ancien fichier, et supprimer la référence à celui-ci dans server.ts
Dernière mise à jour