javascript

Middleware en Express.js: cadena de funciones intermedias

Aprende qué son los middlewares en Express.js, cómo encadenarlos y ejemplos prácticos: logger, autenticación, validación y manejo de errores.

3 min
3 jul

Los middlewares son la pieza que conecta, filtra y protege cada petición en tu servidor Express.

Contexto

Un middleware es una función que recibe la petición (req), la respuesta (res) y la función next, y puede: modificar req o res, ejecutar código, o finalizar la respuesta. Si no finaliza la respuesta, debe llamar a next() para pasar al siguiente middleware de la cadena.

Cadena completa de middlewares

const express = require('express');
const app = express();

// 1. Middleware incorporado: parsear JSON
app.use(express.json());

// 2. Middleware de aplicación: logger
app.use((req, res, next) => {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
    next();
});

// 3. Middleware de ruta: autenticación
function autenticar(req, res, next) {
    const token = req.headers['authorization'];

    if (!token) {
        return res.status(401).json({ error: 'Token requerido' });
    }

    // Simulación de validación
    if (token !== 'Bearer mi-token-secreto') {
        return res.status(403).json({ error: 'Token inválido' });
    }

    req.usuario = { id: 1, nombre: 'Admin' };
    next();
}

// 4. Middleware de ruta: validación de datos
function validarUsuario(req, res, next) {
    const { nombre, email } = req.body;

    if (!nombre || !email) {
        return res.status(400).json({
            error: 'nombre y email son requeridos'
        });
    }

    if (!email.includes('@')) {
        return res.status(400).json({
            error: 'email no tiene formato válido'
        });
    }

    next();
}

// 5. Ruta protegida con middlewares
app.post('/api/usuarios',
    autenticar,
    validarUsuario,
    (req, res) => {
        // Este handler solo se ejecuta si pasó todos los middlewares
        const { nombre, email } = req.body;

        // Simular creación en base de datos
        const usuario = {
            id: Date.now(),
            nombre,
            email,
            creadoPor: req.usuario.nombre
        };

        res.status(201).json(usuario);
    }
);

// 6. Ruta pública (sin autenticación)
app.get('/api/public', (req, res) => {
    res.json({ mensaje: 'Esta ruta es pública' });
});

// 7. Middleware de error (4 parámetros)
app.use((err, req, res, next) => {
    console.error('Error:', err.message);
    res.status(500).json({
        error: 'Error interno del servidor'
    });
});

app.listen(3000, () => {
    console.log('Servidor corriendo en http://localhost:3000');
});

Explicación del flujo

  1. express.json(): parsea el body de la petición como JSON.
  2. Logger: registra cada petición con timestamp, método y URL.
  3. autenticar: verifica el token en el header Authorization. Si falta → 401. Si es inválido → 403. Si es válido → adjunta req.usuario y llama next().
  4. validarUsuario: revisa que nombre y email existan y que el email tenga formato válido.
  5. Handler de ruta: solo se ejecuta si todos los middlewares anteriores llamaron a next().
  6. Middleware de error: atrapa cualquier error que se pase con next(err).

Tip extra: middleware específico vs global

// Middleware global: se aplica a TODAS las rutas
app.use(express.json());
app.use(logger);

// Middleware específico: solo para ciertas rutas
app.use('/api/admin', autenticar); // solo protege rutas que empiecen con /api/admin

// También se puede pasar un array de middlewares
const middlewares = [autenticar, validarUsuario];
app.post('/api/usuarios', middlewares, handler);

El middleware es la navaja suiza de Express: úsalo para mantener tu código limpio y cada responsabilidad en su lugar.

¡Código copiado!