--- tags: ironhack --- Express middlewares === Une application Express reçoit des requêtes HTTP et y répond. On peut ainsi représenter une application Express par un système entrée/sortie: [![](https://docs.google.com/drawings/d/e/2PACX-1vTlMNZulRlVhDC-zffbxfCyxmSPeyWfs6HEeCT5crZBqppB3n5YMWzywwx56Py_OwsmfJMCb4acOcut/pub?w=1057&h=429)](https://docs.google.com/drawings/d/1yCiHtMRqXyEpvVjyLYPN_19JH6ZI2L5abxKdzdQ2OqI/edit) Prenons **une analogie** pour la suite de l'explication et considérons que notre application Express est une usine de voitures : - que chaque requête est une commande - et que chaque réponse est un produit livré : [![](https://docs.google.com/drawings/d/e/2PACX-1vQrAHib0PALPpEPyK4BcloZdTPt-e0O5E77RqNdBOv-bk5hONWIi4EMYnx7L508NZyjLCNaCInd8L8_/pub?w=1057&h=429)](https://docs.google.com/drawings/d/1LAENz6QFY2xaEuvere5yDiNqVc--yeWx7D06BHq8TfA/edit) Comme sur une ligne de montage, la voiture(ie: réponse) va devoir passer par différentes étapes pour sa construction : [![](https://docs.google.com/drawings/d/e/2PACX-1vSBxi9yTJ85n5IUlsyRbo3MoiRpXVogV3RbTHNwTSlq8z-mpcgzq1tcxsYgbXiX3im3_53LZcq48ZhL/pub?w=1185&h=333)](https://docs.google.com/drawings/d/19HLMdonYUeIu1VgdLiaIZrBpK0DS2U2ghmkcofTbjfs/edit) Chaque étape correspondra dans Express à ce qu'on appelle **un middleware**. Dans notre analogie, cela correspondrait à un ouvrier sur la ligne, effectuant une opération : [![](https://docs.google.com/drawings/d/e/2PACX-1vQ7L8R5ZmLb52VIYIKSY2Ji0kXAm6H8ZxME_gF7F7U9RWU_KAIkAksbsMFMgjj5ZIuKLqEz43knIpYK/pub?w=1188&h=565)](https://docs.google.com/drawings/d/1HCtQ1M95bzXNrDJu9E4_DSXCj7WU2_tfeeQsHfOdn9I/edit) Ce qui en code correspondra à : ```js app.use(function (req, res, next) { // // Fabrication du capot // next(); }) ``` Express va donc enchaîner ces fonctions middleware et après chacune passer à la suivante : [![](https://docs.google.com/drawings/d/e/2PACX-1vTSvbosekfkYvsle2noSIhIZFx9x4fiNXmhoj6aV4jLEBO2n-ZecsCfPwdBgXoqI6Eu2dPhxk34He2s/pub?w=1188&h=565)](https://docs.google.com/drawings/d/16vrTL2Iscvu2l0CUXWjSdKF7g9us3Cxts1oShxGR2Ro/edit) La fonction `next` est passée au middleware et lui permet de dire quand sa tâche est finie. C'est parce que sa tâche peut être asynchrone que nous avons besoin d'une telle fonction de callback. **Le dernier middleware renverra lui la réponse : `res.send()` ou `res.render()`...** :::info ✋ On peut interrompre la chaine si une erreur intervient en passant cette fois un paramètre à `next`, typiquement l'erreur : ```js next(new Error("marteau cassé")); ``` cf. la [gestion des erreurs](https://expressjs.com/en/guide/error-handling.html) dans Express. ::: Routes middlewares --- Jusqu'à maintenant, nos middlewares s'appliquent à toutes les requêtes entrantes. Cependant, [`app.use`](http://expressjs.com/en/4x/api.html#app.use) permet de spécifier un `path` avant la première fonction middleware, ce afin de le restreindre à une route en particulier : ```js app.use("/controle-technique", function (req, res, next) { // // vérification du niveau d'huile // next(); }); ``` :::info :bulb: ce `path` est optionnel. ::: On peut également en plus, avoir **plusieurs fonctions middlewares** dans un même `app.use` : ```js= app.use("/controle-technique", function (req, res, next) { // // 1. vérification du niveau d'huile // next(); }, function (req, res, next) { // // 2. vérification de la pression des pneus // next(); }, function (req, res, next) { // // 3. nettoyage du pare-brise // res.send('voiture ok'); }); ``` Ceci nous permet de bien découper chaque fonction. :::success On remarque là encore, l'utilisation de `next()` pour passer à la fonction suivante. ::: :::success On remarque également que la dernière fonction, retourne bien une réponse grâce à `res.send` ligne 18. ::: --- `app.use` répond à tous les verbes HTTP, ie: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`. Si l'on veut qu'un middleware ne s'applique qu'à un certain verbe en particulier, on peut alors utiliser et de la même façon `app.METHOD`, comme par ex: ```js app.get('/', function (req, res, next) { res.send("Bienvenue à notre usine !"); }); ``` Et de la même façon, on peut là encore avoir plusieurs fonctions middlewares, ici 2 fonctions : ```js app.put("/sav", verifMarque, (req, res, next) { // // On procède à l'échange (on a au préalable vérifié la marque) // res.send('echange ok') }); function verifMarque(req, res, next) { // // On vérifie qu'il s'agit bien de notre marque // next(); } ``` :::info :bulb: `verifMarque` qui est notre 1ère fonction middleware, est ici une **fonction nommée**. La 2ème fonction est une fonction anonyme (sans nom). Nous avons donc le choix à ce niveau, mais cela peut s'avèrer pratique si l'on souhaite réutiliser `verifMarque` dans un autre middleware. ::: Pour résumer --- [![](https://docs.google.com/drawings/d/e/2PACX-1vT7fCzOsq4s6bcEgCx6ev4kvYk8U8rQctrFbGyhSJrDhaRs7nv5Dbpp6bgikgmW8090x9lKjU7irJ7E/pub?w=2910&h=1297)](https://docs.google.com/drawings/d/1BhJA4XQr6BMT6p-yxGCvkgWxKpDTK3DNMuPD4gMNTTQ/edit)