patternModeratepending
Middleware pattern -- composable request/response processing
Viewed 0 times
middlewarechainpipelinebefore/aftercomposeExpress
Problem
Adding cross-cutting concerns (auth, logging, validation, error handling) to every endpoint creates duplication. Each endpoint has the same boilerplate wrapping the actual logic.
Solution
Middleware functions wrap the handler, forming a chain. Each middleware can: run code before the handler, modify request/response, short-circuit the chain, or run code after the handler. This is the core pattern behind Express, Koa, Django, Rack, and ASP.NET.
Code Snippets
Composable middleware chain
// Composable middleware (generic)
type Next = () => Promise<void>;
type Middleware = (ctx: Context, next: Next) => Promise<void>;
function compose(middlewares: Middleware[]): Middleware {
return (ctx, next) => {
let index = -1;
function dispatch(i: number): Promise<void> {
if (i <= index) throw new Error('next() called multiple times');
index = i;
const fn = i === middlewares.length ? next : middlewares[i];
return fn ? fn(ctx, () => dispatch(i + 1)) : Promise.resolve();
}
return dispatch(0);
};
}
// Usage
const app = compose([
logger, // logs request + response time
auth, // checks token, sets ctx.user
rateLimit, // checks rate limit
router, // routes to handler
]);Revisions (0)
No revisions yet.