Real-world combination
Request Pipeline = Chain + Strategy + Factory
An HTTP request flows through ordered middleware — each handler's policy is swappable, and the whole stack is assembled from config.
✗ The problem
One giant handler does everything
Auth, rate-limiting, validation and logging are all crammed into a single function — un-reorderable, un-reusable, untestable in isolation.
function handleRequest(req, res) {
if (!checkToken(req)) return res.status(401).end();
if (!checkRate(req)) return res.status(429).end();
if (!validate(req)) return res.status(400).end();
log(req);
runHandler(req, res); // ← buried at the bottom
}
Want JWT instead of API-keys? Skip rate-limiting for admins? Every change means reopening this one function.
✓ The combination
→
→
→
Chain of handlers, each a swappable Strategy, built by a Factory
Chain of Responsibility passes the request through ordered handlers; each handler's policy is a pluggable Strategy (e.g. JWT vs API-key auth); a Factory builds the pipeline from a config list.
pipeline([
auth(jwtStrategy),
rateLimit(),
validate(),
], handler);
// factory assembles the chain from config
function pipeline(mws, h) {
return mws.reduceRight(
(next, mw) => req => mw(req, next), h);
}
Auth
strategy
RateLimit
Validate
Handler
✓ See it live
Watch a request move through the chain, handler by handler
Each handler passes the request to the next — or short-circuits the whole chain with an error response.
Follow the numbered messages top-to-bottom — a missing token short-circuits the chain at Auth; every other handler never even runs.
✓ Takeaway
Composable, reorderable, testable
- Composable: each handler is isolated — Auth doesn't know Validate exists.
- Reorderable: change the config array, the chain rewires itself.
- Testable: test each Strategy (JWT vs API-key) alone, mock the rest of the chain.
- Everywhere: Express/Koa
app.use(), ASP.NET middleware, Redux middleware.
🎯 Combines: Chain of Responsibility (ordered handlers) + Strategy (swappable per-handler policy) + Factory (assemble the pipeline from config).
Back to all topics →