Convenciones de naming para middleware Express
Los middleware en Express deben tener nombres que expliquen qué hacen, no cómo lo hacen. Usa verbos activos: requireAuth, validateBody, logRequest. Evita nombres vagos como checkStuff o middleware1.
Para middleware reutilizable, usa funciones factory que devuelvan el middleware: validateBody(schema), rateLimit({ max: 100 }). Esto permite configuración por ruta sin duplicar código.
Organiza middleware en carpetas por tipo: /middleware/auth/, /middleware/validation/. Los middleware globales (helmet, cors) van en el bootstrap de la app; los específicos de ruta se aplican en los routers. El orden importa: auth antes que validación, validación antes que handlers.
Patrones comunes de middleware Express
El patrón más común es middleware de tres argumentos (req, res, next). Para async/await, envuelve en asyncHandler o usa librerías como express-async-errors que automatizan el catch.
Middleware de error handling tiene cuatro argumentos: (err, req, res, next). Debe ir al final de la cadena. Error tipado: crea clases custom que extiendan Error con propiedades statusCode, code, isOperational.
Para validación, integra Zod o Joi. Ejemplo: validateBody(userSchema) devuelve middleware que parsea req.body y llama next(error) si falla. Usa transform de Zod para sanitizar y castear tipos (dates, emails).
Rate limiting y seguridad en APIs
Implementa rate limiting con express-rate-limit. Config básica: max: 100 requests por IP cada windowMs: 15 * 60 * 1000 (15min). Para APIs públicas, usa límites agresivos (10 req/min); para autenticadas, más permisivos (100 req/min).
Combina rate limit con slow-down: en lugar de bloquear, retrasa respuestas progresivamente (de 0ms a 1000ms). Útil para endpoints de login/signup vulnerables a brute force.
Otras capas de seguridad: helmet para headers (CSP, HSTS), express-validator para sanitizar inputs, hpp contra parameter pollution. En producción, usa API Gateway (AWS API Gateway, Kong) para WAF, geoblocking y DDoS protection antes que llegue a tu app.
Testing y debugging de middleware
Para testear middleware, usa supertest con requests HTTP reales: request(app).get('/api/users').expect(200). Mockea req, res, next con node-mocks-http para tests unitarios de middleware aislado.
Usa DEBUG=express:* para ver logs internos de Express. Para tracing distribuido, añade correlation IDs en un middleware temprano y propágalos en headers X-Correlation-ID a servicios downstream.
Errores comunes: olvidar llamar next() (request cuelga), llamar next() después de enviar respuesta (cannot set headers error), modificar req/res sin TypeScript types custom. Usa @types/express + module augmentation para tipado estricto de propiedades custom en req.user, etc.