Escribiendo middleware para uso en aplicaciones Express
Las funciones Middleware son funciones que tienen acceso al objeto de solicitud (req), el objeto de respuesta (res), y la función next en el ciclo de solicitud y respuesta de la aplicación. La función siguiente es una función en el router Express que, cuando se invoca, ejecuta el middleware sucediendo al middleware actual.
Las funciones de Middleware pueden realizar las siguientes tareas:
- Ejecutar cualquier código.
- Realizar cambios en la solicitud y en los objetos de respuesta.
- Terminar el ciclo de solicitud de respuesta.
- Llama al siguiente middleware en la pila.
Si la función actual de middleware no termina el ciclo de solicitud de respuesta, debe llamar a next() para pasar el control a la siguiente función de middleware. De lo contrario, la solicitud quedará colgada.
La siguiente figura muestra los elementos de una llamada a una función de middleware:

A partir de Express 5, las funciones de middleware que devuelven una Promise llamarán next(value) cuando rechacen o lancen un error. next será llamado con el valor rechazado o con el error arrojado.
Ejemplo
He aquí un ejemplo de una simple aplicación “Hola Mundo” Express.
El resto de este artículo definirá y añadirá tres funciones de middleware a la aplicación:
una llamada myLogger que imprime un simple mensaje de registro, uno llamado requestTime que
muestra la marca de tiempo de la petición HTTP, y uno llamado validateCookies que valida las cookies entrantes.
const express = require('express');const app = express();
app.get('/', (req, res) => { res.send('Hello World!');});
app.listen(3000);Función Middleware myLogger
Aquí hay un ejemplo simple de una función middleware llamada “myLogger”. Esta función solo imprime
“LOGGED” cuando una solicitud a la aplicación pasa a través de ella. La función middleware está asignada a una variable
llamada myLogger.
const myLogger = function (req, res, next) { console.log('LOGGED'); next();};Tenga en cuenta la llamada anterior a next(). Llamar a esta función invoca la siguiente función de middleware en
la aplicación. La función next() no es parte del Nodo. s o Express API, pero es el tercer argumento
que se pasa a la función middleware. La función next() podría ser nombrada cualquier cosa,
pero por convención siempre se llama “siguiente”. Para evitar la confusión, utilice siempre esta convención.
Para cargar la función middleware, llama a app.use(), especificando la función middleware.
Por ejemplo, el siguiente código carga la función middleware myLogger antes de la ruta a la ruta raíz (/).
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);Cada vez que la aplicación recibe una solicitud, imprime el mensaje “LOGGED” en el terminal.
El orden de carga de middleware es importante: las funciones de middleware que se cargan primero también se ejecutan primero.
Si myLogger es cargado después de la ruta a la ruta raíz, la solicitud nunca llega a ella y la aplicación no imprime “LOGGED”, porque el manejador de rutas de la ruta raíz termina el ciclo de solicitud de respuesta.
La función Middleware myLogger simplemente imprime un mensaje, luego pasa la solicitud a la siguiente función de middleware en la pila llamando a la función next().
Tiempo de solicitud de la función Middleware
A continuación, crearemos una función de middleware llamada “requestTime” y agregaremos una propiedad llamada requestTime
al objeto de la solicitud.
const requestTime = function (req, res, next) { req.requestTime = Date.now(); next();};La aplicación ahora utiliza la función de middleware requestTime. Además, la función de callback de la ruta raíz utiliza la propiedad que la función middleware añade a req (el objeto de la solicitud).
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);Cuando hace una solicitud a la raíz de la aplicación, la aplicación ahora muestra la marca de tiempo de su solicitud en el navegador.
Función Middleware validateCookies
Finalmente, crearemos una función de middleware que valida las cookies entrantes y envía una respuesta 400 si las cookies no son válidas.
Aquí hay una función de ejemplo que valida las cookies con un servicio externo asíncrono.
async function cookieValidator(cookies) { try { await externallyValidateCookie(cookies.testCookie); } catch { throw new Error('Invalid cookies'); }}Aquí usamos el cookie-parser middleware para analizar las cookies entrantes del objeto req y pasarlas a nuestra función cookieValidator. El middleware validateCookies devuelve una Promesa que al rechazar activará automáticamente nuestro gestor de errores.
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);Observe cómo next() es llamado después de await cookieValidator(req.cookies). Esto asegura que si
cookieValidator resuelve, se llamará al siguiente middleware en la pila. Si pasas algo
a la función next() (excepto la cadena 'route' o 'router'), Express considera que la actual petición
es un error y se saltará cualquier función
que no sea de manejo de enrutamiento y middleware restante.
Debido a que tiene acceso al objeto de solicitud, el objeto de respuesta, la siguiente función de middleware en la pila, y el nodo entero. s API, las posibilidades con funciones middleware son infinitas.
Para más información sobre middleware exprés, vea: Usando middleware exprés.
Middleware configurable
Si necesita que su middleware sea configurable, exporte una función que acepte un objeto de opciones u otros parámetros, , que luego devuelve la implementación de middleware basada en los parámetros de entrada.
Archivo: my-middleware.js
module.exports = function (options) { return function (req, res, next) { // Implement the middleware function based on the options object next(); };};El middleware ahora puede ser usado como se muestra a continuación.
const mw = require('./my-middleware.js');
app.use(mw({ option1: '1', option2: '2' }));Consulte cookie-session y compression para ver ejemplos de middleware configurable.