intermediate

Middleware

Compose request handlers for cross-cutting concerns while controlling order, ownership, short-circuiting, and side effects.

Middleware functions wrap request handling with signature `(req, res, next) => void` (Express-style) or framework hooks — they compose cross-cutting behavior in explicit order.

					app.use(requestId());
app.use(express.json({ limit: '1mb' }));
app.use(authenticate);
app.get('/orders/:id', authorize('orders:read'), getOrder);

function asyncHandler(fn) {
  return (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
}
				

Order matters: body parsing before validation; auth before authorization; error middleware last (four-arg handler). Short-circuit by sending a response without calling `next()`.

Frameworks differ (Fastify hooks, Koa onion model) but the design question is the same: who owns side effects and failure paths.

On interviews: diagram middleware order for auth + validation; explain error propagation to centralized handler; contrast global vs route-scoped middleware.

Common pitfalls: calling `next()` after response sent; async middleware without error forwarding; god middleware that knows every route.

The trade-off is balancing simplicity, performance, safety, and operability — name which axis you optimized and what cost you accepted.

Checklist:

  • Single responsibility per middleware.
  • Document required order in README or module.
  • Centralize error formatting.
  • Avoid mutable baggage on `req` without types/discipline.