Como su propio nombre indica, es un software que se aplica en la mitad de algo, específicamente entre dos capas, aplicaciones o servicios.
El objetivo de los middlewares es crear un puente entre estas capas. En el desarrollo web, lo más normal es ver los middlewares entre la solicitud (request) y la respuesta (response), con el objetivo de aplicar alguna validación o comprobación.
Funciones principales
Estos son los usos más comunes:
- Autenticación y Autorización: Antes de mostrarle el perfil a un usuario, el middleware revisa si tiene una sesión activa o un token válido. Si no, lo rebota a “Login”.
- Logging y Monitoreo: Registra cada visita, el tiempo de respuesta y si hubo errores, guardando todo en una base de datos de control.
- Manejo de Errores: Atrapa cualquier fallo en la lógica de la app para que el usuario no vea una pantalla blanca, sino un mensaje amigable.
- Parseo de Datos: Convierte el texto plano que viene de un formulario en un objeto JSON que tu código pueda entender fácilmente.
- Seguridad (CORS, Helmet): Añade capas de protección contra ataques comunes o gestiona quién tiene permiso para pedir datos desde otros dominios.
El flujo de una petición con Middlewares
Para el usuario que interactúa con nuestro sitio web solo hay dos procesos visibles, la petición y la respuesta. Sin embargo, por detrás puede haber pasado lo siguiente:
- Petición: El usuario solicita entrar al dashboard financiero en el ERP de su empresa mediante un clic.
- Middleware de autenticación y autorización: La aplicación, antes de servirle al cliente con la página solicitada, comprueba si el usuario tiene la sesión iniciada y si su rol le permite ver la información que está solicitando.
- Respuesta: Si el usuario cumple con los requisitos para la visualización del panel solicitado, se le devolverá la pantalla del dashboard financiero. En caso contrario, recibirá un mensaje de error.
Este es un flujo muy común en la mayoría de frameworks de desarrollo web. De todas formas, entre la petición y la respuesta podrían haber ido muchas más capas de validación, dependiendo de la complejidad de la tarea solicitada. Veámoslo en el siguiente ejemplo.
Ejemplo práctico (express.js)
En este ejemplo vamos a aplicar dos capas de validación. Se trata de un endpoint que permite a los usuarios publicar contenido en un blog. Para ello debemos comprobar lo siguiente:
- Que el usuario tiene la sesión iniciada y cuenta con alguno de los roles de
editoroadmin. Si no comprobáramos esto, cualquiera podría publicar en nuestro blog. - La segunda comprobación va a ser del contenido mandado por el cliente. El artículo debe tener por lo menos título y contenido y estos deben ser mayores a 5 y 20 caracteres respectivamente.
La primera comprobación se realizará con el middleware llamado checkAuth. La segunda comprobación con validatePost.
const express = require('express');
const app = express();
// Middleware para entender JSON (Viene incluido en Express)
app.use(express.json());
// 1. MIDDLEWARE DE AUTENTICACIÓN Y ROLES
const checkAuth = (req, res, next) => {
const token = req.headers['authorization'];
const userRole = req.headers['role']; // Simulación simple
if (!token) {
return res.status(401).json({ error: "No hay token, acceso denegado." });
}
if (userRole !== 'editor' && userRole !== 'admin') {
return res.status(403).json({ error: "No tienes permisos suficientes." });
}
// Si todo está bien, guardamos al usuario en el objeto 'req' para usarlo después
req.user = { id: 123, role: userRole };
next();
};
// 2. MIDDLEWARE DE VALIDACIÓN DE FORMATO
const validatePost = (req, res, next) => {
const { titulo, contenido } = req.body;
if (!titulo || titulo.length < 5) {
return res.status(400).json({ error: "El título es obligatorio y debe tener al menos 5 caracteres." });
}
if (!contenido || contenido.length < 20) {
return res.status(400).json({ error: "El contenido es demasiado corto." });
}
next();
};
// --- LA RUTA FINAL ---
// Aquí encadenamos los middlewares en orden: Primero Auth, luego Validación.
app.post('/api/posts', checkAuth, validatePost, (req, res) => {
// Si llegamos aquí, es porque AMBOS middlewares llamaron a next()
console.log(`Usuario ${req.user.id} está creando un post.`);
res.status(201).json({
message: "¡Post creado con éxito!",
data: req.body
});
});
app.listen(3000, () => console.log("Servidor en puerto 3000"));
Ventajas de usar middlewares
- Modularidad: Al separar la lógica de validación en middlewares te permite añadir o quitarlos en cualquier lado del código, sin necesidad de reescribir lo mismo una y otra vez.
- Mantenibilidad: Al estar la lógica encapsulada en un middleware, si hay que aplicar un cambio, se realiza directamente en el middleware afectado y no en todo el código donde se haga la validación.
- Seguridad por capas: Permiten crear aplicaciones mucho más robustas al aplicarlos en serie uno detrás de otro. Cuantas más capas de middlewares apliquemos, nuestra aplicación será mucho más robusta ante peticiones malformadas o accesos no autorizados.
Conclusión
Como hemos visto, los middlewares no son solo una capa extra de código; son el sistema circulatorio de una aplicación moderna. Sin ellos, nuestras rutas estarían saturadas de código repetitivo, mezclando la lógica de negocio con validaciones, seguridad y registros.
Dominar los middlewares es el paso definitivo para dejar de escribir “scripts” y empezar a construir arquitecturas de software profesionales. La próxima vez que veas una petición fluyendo en tu servidor, visualiza ese camino de obstáculos que has construido para asegurar que solo lo mejor llegue a tu base de datos.