REST API avec Node/TS/Express + OpenAPI

Évolution de la solution précédente reprise à zéro. Donc un serveur Node avec Typescript ce coup-ci, dont les routes sont pilotées par l’openAPI.

On commence avec le tuto bien foutu « How to set up TypeScript with Node.js and Express » de LogRocket. Sur lequel on va reprendre la solution précédente morceau par morceau, et c’est là que ça devient intéressant.

En résumé, nous aurons 2 @types à ajouter, ainsi que concurrently pour essayer, lors des installs pour que ça fonctionne et adapter les 2 codes principaux.

npm i -D concurrently
npm i @types/cors
npm i @types/swagger-ui-express

Il faudra également faire attention à votre git bash, dans le fichier .bash_profile ou rc, activer le support des couleurs pour concurrently.

export FORCE_COLOR="1"

Le makeApp s’adapte sous forme d’une classe TS

import SwaggerParser from "@apidevtools/swagger-parser";
import SwaggerRoutes from "swagger-routes-express"
import express from "express";
import cors from "cors"
import swaggerUi from "swagger-ui-express"

export class MakeApp {
    static async make() {
        const parser = new SwaggerParser()
        const apiDescription = await parser.validate('./api/openapi.yaml')
        const connect = SwaggerRoutes.connector({
            getCore: async (req, res, next) => {
                console.log("getCore")
                res.json([])
            }
        }, apiDescription, {
            onCreateRoute: (method, descriptor) => {
                const [path, ...handlers] = descriptor
                console.log('created route', method, path, handlers)
            }
        })
        const app = express()

...

        return app
    }
}

Et l’index de bootstrap légèrement adapté

import { MakeApp } from "./makeApp";
import dotenv from "dotenv"

dotenv.config()

const port = process.env.PORT || 3000

MakeApp.make()
    .then(app => app.listen(port))
    .then(() => {
        console.log(`[server]: Server is running at http://localhost:${port}`)
    })
    .catch(err => {
        console.error('Caught error', err)
    })

Pour les détails je vous invite à consulter le GitHub du projet ;). L’API a été simplifiée un peu et l’ajout de nodemon et concurrently.

Pas de contrôleur séparé dans ce test, flemme, tout simplement, le test est fonctionnel et on verra si je le pousse plus loin en terme de comparatif.

Être piloté par openAPI ou par le code et générer son swagger ?

C’est la question, vous trouverez la seconde option partout mais j’aimais l’idée que l’on puisse architecturer de manière agnostique son API et l’implémenter ensuite en collant les méthodes aux routes. Il est vrai que pour les mises à jour fréquentes, générer la doc sur base du code est plus simple, mais l’erreur est plus vite faite aussi me semble-t-il.

« Bricoler ainsi » ou framework prêt à l’emploi ?

Là encore, bonne question, ici j’ai un truc qui fonctionne, dans le bon esprit Node mais qui reste un assemblage dépendant de paquets divers et qui ne seront plus mis à jour (vérifié pour certains). De par leur nature et pour quoi ils ont été conçus, et pour ce que l’on souhaite faire avec dans le futur. Du coup j’ai regarder les frameworks TS tel que Nest ou Foal. Reste à déterminer avec 1 test de chaque lequel correspondrait au projet cible :).

Nest basé sur l’idée Angular est très populaire donc je trouverais facilement de la doc, quant à Foal c’est le petit nouveau full TS prometteur avec pas mal de built-in, mais à comparer avec le même type de test que cet article, en y ajoutant l’auth et la sécu pour les besoins clefs de base. Une connexion db et tester leur ORM pourrait également être un bon point et faire un article ensuite :).

Liste des ressources utilisées

Laisser un commentaire

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

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.