Écriture de middleware pour utilisation dans les applications Express
Aussi, la fonction callback de la route du chemin racine utilise la propriété que la fonction middleware ajoute à req (l’objet de requête). L’application utilise maintenant la fonction middleware requestTime.
Les fonctions Middleware peuvent effectuer les tâches suivantes :
- Exécuter n’importe quel code.
- Effectuez des modifications à la requête et aux objets de réponse.
- Termine le cycle de réponse de la requête.
- Appelez le prochain middleware dans la pile.
Si la fonction middleware actuelle ne met pas fin au cycle de réponse de requête, elle doit appeler next() pour passer le contrôle à la prochaine fonction du middleware. Sinon, la demande sera laissée en suspens.
La figure suivante montre les éléments d’un appel de fonction middleware :

À partir de Express 5, les fonctions middleware qui retournent une Promise appelleront next(value) quand elles rejettent ou lancent une erreur. next sera appelé avec la valeur rejetée ou avec l’erreur levée.
Exemple
Voici un exemple de simple application “Hello World” Express.
Le reste de cet article va définir et ajouter trois fonctions middleware à l’application :
un appelé myLogger qui affiche un message de log simple. on appelle requestTime que
affiche l’horodatage de la requête HTTP, et un appelé validateCookies qui valide les cookies entrants.
const express = require('express');const app = express();
app.get('/', (req, res) => { res.send('Hello World!');});
app.listen(3000);import express from 'express';
const app = express();
app.get('/', (req, res) => { res.send('Hello World!');});
app.listen(3000);import express, { type Express, type Request, type Response } from 'express';
const app: Express = express();
app.get('/', (req: Request, res: Response) => { res.send('Hello World!');});
app.listen(3000);Fonction Middleware myLogger
Voici un exemple simple d’une fonction middleware appelée “myLogger”. Cette fonction affiche seulement
“LOGGED” lorsqu’une requête vers l’application passe à travers elle. La fonction middleware est assignée à une variable
nommée myLogger.
const myLogger = function (req, res, next) { console.log('LOGGED'); next();};import { type Request, type Response, type NextFunction } from 'express';
const myLogger = function (req: Request, res: Response, next: NextFunction) { console.log('LOGGED'); next();};Here myLogger is defined on its own rather than passed directly to app.use(), so TypeScript has
no context to infer its parameters and they are annotated explicitly. You can instead type the whole
function as RequestHandler, which types req, res, and next for you. When the middleware is
written inline in the app.use() call, Express infers those three parameters and no annotations are
needed.
Notez l’appel ci-dessus à next(). Appeler cette fonction appelle la prochaine fonction du middleware dans
l’application. La fonction next() n’est pas une partie du noeud. s ou API Express, mais est le troisième argument
qui est passé à la fonction middleware. La fonction next() pourrait être nommée quoi que ce soit,
mais par convention elle est toujours nommée “next”. Pour éviter toute confusion, utilisez toujours cette convention.
Pour charger la fonction middleware, appelez app.use(), en spécifiant la fonction middleware.
Par exemple, le code suivant charge la fonction middleware myLogger avant la route vers le chemin racine (/).
const express = require('express');const app = express();
const myLogger = function (req, res, next) { console.log('LOGGED'); next();};
app.use(myLogger);
app.get('/', (req, res) => { res.send('Hello World!');});
app.listen(3000);import express from 'express';
const app = express();
const myLogger = function (req, res, next) { console.log('LOGGED'); next();};
app.use(myLogger);
app.get('/', (req, res) => { res.send('Hello World!');});
app.listen(3000);import express, { type Express, type Request, type Response, type NextFunction } from 'express';
const app: Express = express();
const myLogger = function (req: Request, res: Response, next: NextFunction) { console.log('LOGGED'); next();};
app.use(myLogger);
app.get('/', (req: Request, res: Response) => { res.send('Hello World!');});
app.listen(3000);Chaque fois que l’application reçoit une demande, elle affiche le message “LOGGGED” vers le terminal.
L’ordre de chargement du middleware est important : les fonctions du middleware qui sont chargées en premier sont également exécutées en premier.
Si myLogger est chargé après la route vers le chemin racine, la requête ne l’atteint jamais et l’application n’affiche pas “LOGGED”, parce que le gestionnaire de route du chemin racine termine le cycle de réponse de requête.
La fonction du middleware myLogger affiche simplement un message, passe ensuite la requête à la prochaine fonction middleware de la pile en appelant la fonction next().
Middleware fonction requestTime
Ensuite, nous allons créer une fonction middleware appelée “requestTime” et ajouter une propriété appelée requestTime
à l’objet requête.
Because the middleware adds a property to req, extend the request type in TypeScript with
declaration merging. Declare
the property (as optional, since a middleware may not run for every request) in a .d.ts file that
is part of your project:
declare global { namespace Express { interface Request { requestTime?: number; } }}
export {};TypeScript picks up the file automatically, so no tsconfig.json change is needed unless you have
set a custom include that does not cover its location. See
Extending the API in TypeScript for
adding other custom properties and methods.
const requestTime = function (req, res, next) { req.requestTime = Date.now(); next();};import { type Request, type Response, type NextFunction } from 'express';
const requestTime = function (req: Request, res: Response, next: NextFunction) { req.requestTime = Date.now(); next();};The app now uses the requestTime middleware function. Also, the callback function of the root path route uses the property that the middleware function adds to req (the request object).
const express = require('express');const app = express();
const requestTime = function (req, res, next) { req.requestTime = Date.now(); next();};
app.use(requestTime);
app.get('/', (req, res) => { let responseText = 'Hello World!<br>'; responseText += `<small>Requested at: ${req.requestTime}</small>`; res.send(responseText);});
app.listen(3000);import express from 'express';
const app = express();
const requestTime = function (req, res, next) { req.requestTime = Date.now(); next();};
app.use(requestTime);
app.get('/', (req, res) => { let responseText = 'Hello World!<br>'; responseText += `<small>Requested at: ${req.requestTime}</small>`; res.send(responseText);});
app.listen(3000);import express, { type Express, type Request, type Response, type NextFunction } from 'express';
const app: Express = express();
const requestTime = function (req: Request, res: Response, next: NextFunction) { req.requestTime = Date.now(); next();};
app.use(requestTime);
app.get('/', (req: Request, res: Response) => { let responseText = 'Hello World!<br>'; responseText += `<small>Requested at: ${req.requestTime}</small>`; res.send(responseText);});
app.listen(3000);Lorsque vous faites une demande à la racine de l’application, l’application affiche maintenant l’horodatage de votre requête dans le navigateur.
format@@0 Middleware function validateCookies
Enfin, nous allons créer une fonction middleware qui valide les cookies entrants et envoie une réponse 400 si les cookies sont invalides.
Voici un exemple de fonction qui valide les cookies avec un service asynchrone externe.
async function cookieValidator(cookies) { try { await externallyValidateCookie(cookies.testCookie); } catch { throw new Error('Invalid cookies'); }}async function cookieValidator(cookies: Record<string, string>) { try { await externallyValidateCookie(cookies.testCookie); } catch { throw new Error('Invalid cookies'); }}Le middleware validateCookies retourne une Promesse que si le rejet déclenchera automatiquement notre gestionnaire d’erreurs. Ici, nous utilisons le middleware cookie-parser pour analyser les cookies entrants de l’objet req et les passer à notre fonction cookieValidator.
const express = require('express');const cookieParser = require('cookie-parser');const cookieValidator = require('./cookieValidator');
const app = express();
async function validateCookies(req, res, next) { await cookieValidator(req.cookies); next();}
app.use(cookieParser());
app.use(validateCookies);
// error handlerapp.use((err, req, res, next) => { res.status(400).send(err.message);});
app.listen(3000);import express from 'express';import cookieParser from 'cookie-parser';import cookieValidator from './cookieValidator';
const app = express();
async function validateCookies(req, res, next) { await cookieValidator(req.cookies); next();}
app.use(cookieParser());
app.use(validateCookies);
// error handlerapp.use((err, req, res, next) => { res.status(400).send(err.message);});
app.listen(3000);import express, { type Express, type Request, type Response, type NextFunction } from 'express';import cookieParser from 'cookie-parser';import cookieValidator from './cookieValidator';
const app: Express = express();
async function validateCookies(req: Request, res: Response, next: NextFunction) { await cookieValidator(req.cookies); next();}
app.use(cookieParser());
app.use(validateCookies);
// error handlerapp.use((err: Error, req: Request, res: Response, next: NextFunction) => { res.status(400).send(err.message);});
app.listen(3000);Notez comment next() est appelé après wait cookieValidator(req.cookies). Cela garantit que si
cookieValidator résoud, le prochain middleware de la pile sera appelé. Si vous passez quelque chose
à la fonction next() (sauf la chaîne 'route' ou 'router'), Express considère que la requête
actuelle est une erreur et ignorera toute fonction de routage et de middleware
qui ne gère pas les autres fonctions de routage.
Parce que vous avez accès à l’objet requête, à l’objet de réponse, à la prochaine fonction du middleware dans la pile, et à l’ensemble du nœud. s API, les possibilités avec les fonctions du middleware sont infinies.
Pour plus d’informations sur le middleware Express, voir : Utiliser un middleware Express.
Logiciel middleware configurable
Si vous avez besoin que votre middleware soit configurable, exportez une fonction qui accepte un objet d’options ou d’autres paramètres, qui retourne ensuite l’implémentation du middleware en fonction des paramètres d’entrée.
module.exports = function (options) { return function (req, res, next) { // Implement the middleware function based on the options object next(); };};export default function (options) { return function (req, res, next) { // Implement the middleware function based on the options object next(); };}import { type Request, type Response, type NextFunction } from 'express';
export default function (options: Record<string, unknown>) { return function (req: Request, res: Response, next: NextFunction) { // Implement the middleware function based on the options object next(); };}Le middleware peut maintenant être utilisé comme montré ci-dessous.
const mw = require('./my-middleware.cjs');
app.use(mw({ option1: '1', option2: '2' }));import mw from './my-middleware.mjs';
app.use(mw({ option1: '1', option2: '2' }));Reportez-vous à cookie-session et compression pour des exemples de middleware configurables.