Lección 5 de 12 · Lectura y práctica
Creación y uso de middlewares en Express
CONCEPTO CLAVE: Los middlewares en Express son funciones que tienen acceso al objeto de solicitud (req), al objeto de respuesta (res) y al siguiente middleware en el ciclo de solicitud-respuesta de la aplicación. Son.
Del concepto a la práctica
Taller de esta lección
Un middleware puede añadir contexto sin decidir el resultado final. En un museo, registrar el método y la ruta ayuda a rastrear una petición, mientras que otro middleware puede exigir una cabecera para una zona interna. El orden importa: el parser debe ejecutarse antes de leer JSON y una comprobación debe estar montada antes de la ruta protegida.
Ejemplo resuelto
function auditoria(req,res,next){ req.inicio = Date.now(); next(); } permite que la ruta use el dato. Otro middleware puede comprobar req.get('x-sala'); si falta, responde 400, y si existe llama a next(). Montados como app.use(auditoria) y app.use('/interno', requiereSala), afectan a ámbitos distintos. La cabecera x-sala solo ilustra validación: cualquier cliente puede inventarla, por lo que no autentica usuarios ni protege una zona real.
Pruébalo
Añade un middleware que cuente solicitudes en memoria local.
Añade
requiereSalasolo bajo/interno.Envía una petición con y sin
x-sala.Comprueba que cada petición termina en respuesta o en
next().
Error frecuente: olvidar next() en la rama válida. Corrígelo retornando next() tras la comprobación; si no, la petición queda esperando hasta agotar el tiempo.
Comprueba tu resultado
Una petición pública debe conservar su respuesta normal. La ruta interna sin cabecera debe devolver 400 y no ejecutar su controlador. Con la cabecera, el controlador debe ejecutarse una vez y el contador debe aumentar una sola unidad.

Mapa de prácticaEl navegador envía una solicitud a la API. El servidor valida la operación y consulta los datos; después devuelve una respuesta que el navegador puede mostrar. La base de datos se comunica con el servidor y no directamente con el navegador.
Ver la infografía en tamaño completo ↗Creación y Uso de Middlewares en Express
En el desarrollo de APIs RESTful con Node.js y Express, los middlewares constituyen uno de los conceptos más poderosos y versátiles del framework. Permiten crear capas de procesamiento que se ejecutan de forma secuencial, facilitando la separación de preocupaciones y la reutilización de código.
¿Qué es un Middleware?
Un middleware es esencialmente una función que recibe tres parámetros: request, response y next. Cada middleware puede:
- Ejecutar cualquier código.
- Realizar cambios en los objetos request y response.
- Terminar el ciclo de solicitud-respuesta.
- Llamar al siguiente middleware en la pila.
Tipos de Middlewares en Express
| Tipo | Descripción | Ejemplo de uso |
|---|---|---|
| Integrado | Incluido con Express | express.json(), express.static() |
| De terceros | Instalados via npm | morgan, cors, helmet |
| Nivel de aplicación | Aplica a todas las rutas | Autenticación global |
| Nivel de router | Aplica a rutas específicas | Middleware por grupo de rutas |
| Nivel de manejo de errores | Con firma de 4 parámetros | Gestión centralizada de errores |
Creando tu Primer Middleware Personalizado
Veamos cómo crear un middleware desde cero. Empezaremos con un ejemplo sencillo que registre información de cada petición:
// middleware/logger.js
const loggerMiddleware = (req, res, next) => {
const timestamp = new Date().toISOString();
const method = req.method;
const url = req.originalUrl;
console.log(`[${timestamp}] ${method} ${url}`);
// No olvides llamar a next() para continuar
next();
};
module.exports = loggerMiddleware;
next() o envie una respuesta. Olvidar esto provocará que la petición quede colgada indefinidamente.Aplicando Middlewares en tu Aplicación
Ahora veamos cómo usar este middleware en tu servidor Express:
// app.js
const express = require('express');
const loggerMiddleware = require('./middleware/logger');
const app = express();
// Middleware a nivel de aplicación - se ejecuta en TODAS las peticiones
app.use(loggerMiddleware);
// También puedes pasar opciones a tu middleware
app.use('/api', loggerMiddleware);
app.get('/users', (req, res) => {
res.json({ users: [] });
});
app.listen(3000, () => {
console.log('Servidor corriendo en puerto 3000');
});
Middlewares con Parámetros
A veces necesitas que tu middleware acepte configuraciones. Para esto, puedes factory functions:
// middleware/validateAuth.js
const validateAuth = (options = {}) => {
const { required = true, roles = [] } = options;
return (req, res, next) => {
const token = req.headers.authorization;
if (!token && required) {
return res.status(401).json({
error: 'Token de autenticación requerido'
});
}
// Lógica de validación aquí...
req.user = { id: 1, role: 'admin' }; // Simulación
next();
};
};
module.exports = validateAuth;
// Uso:
app.get('/admin', validateAuth({ roles: ['admin'] }), (req, res) => {
res.json({ message: 'Zona administrativa' });
});
Middlewares de Validación de Datos
Un caso de uso muy común es la validación de datos de entrada. Veamos un middleware para validar el cuerpo de una solicitud:
// middleware/validateUser.js
const validateUser = (req, res, next) => {
const { name, email, password } = req.body;
const errors = [];
// Validar nombre
if (!name || typeof name !== 'string' || name.length < 2) {
errors.push('El nombre debe tener al menos 2 caracteres');
}
// Validar email con expresión regular
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!email || !emailRegex.test(email)) {
errors.push('Email inválido');
}
// Validar contraseña
if (!password || password.length < 8) {
errors.push('La contraseña debe tener al menos 8 caracteres');
}
if (errors.length > 0) {
return res.status(400).json({ errors });
}
next();
};
// Uso en ruta
app.post('/users', validateUser, (req, res) => {
// Aquí ya sabes que los datos son válidos
const user = req.body;
res.status(201).json({ message: 'Usuario creado', user });
});
- Define el middleware con acceso a req, res y next.
- Extrae los datos a validar del objeto request.
- Aplica tus reglas de validación.
- Si hay errores, responde inmediatamente con status 400.
- Si todo está bien, llama a next() para continuar.
Middlewares Asíncronos
En aplicaciones reales, frecuentemente necesitarás realizar operaciones asíncronas dentro de tus middlewares:
// middleware/checkDatabase.js
const checkDatabase = async (req, res, next) => {
try {
// Simulación de consulta a base de datos
const dbConnected = await verifyDatabaseConnection();
if (!dbConnected) {
return res.status(503).json({
error: 'Servicio de base de datos no disponible'
});
}
req.dbConnected = true;
next();
} catch (error) {
next(error); // Pasa el error al siguiente middleware de errores
}
};
module.exports = checkDatabase;
next(error). Express lo capturará y lo enviará al middleware de manejo de errores.Middleware de Manejo de Errores
Express tiene un tipo especial de middleware con cuatro parámetros que se encarga de manejar errores:
// middleware/errorHandler.js
const errorHandler = (err, req, res, next) => {
console.error('Error:', err.stack);
const statusCode = err.statusCode || 500;
const message = err.message || 'Error interno del servidor';
res.status(statusCode).json({
error: {
message,
status: statusCode,
timestamp: new Date().toISOString(),
path: req.path
}
});
};
module.exports = errorHandler;
// Uso - debe ser el ÚLTIMO middleware registrado
app.use(errorHandler);
Un middleware de manejo de errores debe tener siempre cuatro parámetros. Express reconoce esta firma especial y sabe que se trata de un handler de errores.
Encadenando Middlewares
Puedes aplicar múltiples middlewares a una misma ruta. Se ejecutarán en orden:
app.post(
'/products',
validateProduct, // 1. Valida los datos
checkPermissions, // 2. Verifica permisos del usuario
checkDatabase, // 3. Verifica conexión a BD
async (req, res) => { // 4. Handler final
const product = await ProductService.create(req.body);
res.status(201).json(product);
}
);
Middlewares de Terceros Útiles
Ver más
Existen muchos middlewares populares que puedes instalar via npm:
- morgan: Logger HTTP para desarrollo y producción.
- cors: Habilita CORS (Cross-Origin Resource Sharing).
- helmet: Configura headers de seguridad HTTP.
- express-rate-limit: Limita las solicitudes repetidas.
- express-validator: Validación y sanitización de datos.
// Instalación
npm install morgan cors helmet express-rate-limit
// Uso básico
const morgan = require('morgan');
const cors = require('cors');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
app.use(morgan('dev'));
app.use(cors());
app.use(helmet());
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutos
max: 100 // límite de 100 solicitudes por ventana
});
app.use('/api', limiter);
Organización de Middlewares
Para proyectos grandes, organiza tus middlewares en carpetas temáticas:
/src
/middleware
/auth
validateToken.js
requireRole.js
/validation
validateUser.js
validateProduct.js
/security
rateLimiter.js
cors.js
/logging
logger.js
requestId.js
errorHandler.js
app.js
Resumen Práctico
| Patrón | Sintaxis | Uso |
|---|---|---|
| Básico | (req, res, next) => {} |
Logging, parsing simple |
| Con opciones | (options) => (req, res, next) => {} |
Configuraciones dinámicas |
| De errores | (err, req, res, next) => {} |
Manejo centralizado de errores |
| Async | async (req, res, next) => {} |
Operaciones con BD o APIs externas |
Los middlewares son el alma de Express. Dominar su uso te permitirá crear APIs robustas, mantenibles y escalables. Practica creando tus propios middlewares y verás cómo tu código se vuelve mucho más limpio y modular.
¿Cuál es el orden correcto de los parámetros en un middleware de manejo de errores de Express?
- A) req, res, next, error
- B) error, req, res, next
- C) req, error, res, next
- D) next, req, res, error
¿Qué sucede si un middleware no llama a next() ni envía una respuesta?
- A) El servidor se reinicia automáticamente
- B) La petición queda colgada indefinidamente
- C) Express ignora el middleware automáticamente
- D) Se genera un error 500 inmediatamente
Sigue con Construcción de APIs RESTful con Node.js y Express
Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.
Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.