Chain of Responsibility Pattern: Processing Pipelines
design-patternsbehavioralchain-of-responsibility

Intent
Chain of Responsibility avoids coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. It chains the receiving objects and passes the request along the chain.
The Problem
Without this pattern, validation code becomes endless if-else:
function handleRequest(req: Request) {
if (!req.headers.auth) {
return { status: 401 };
}
if (rateLimiter.isExceeded(req.ip)) {
return { status: 429 };
}
// Finally, business logic...
}The Solution: Chain of Responsibility
classDiagram
class Handler {
<<interface>>
+setNext(handler): Handler
+handle(request): Response
}
class BaseHandler {
-next: Handler
+handle(request): Response
}
Handler <|.. BaseHandler
BaseHandler o--> HandlerTypeScript Implementation
abstract class MiddlewareHandler {
private next: MiddlewareHandler | null = null;
setNext(handler: MiddlewareHandler): MiddlewareHandler {
this.next = handler;
return handler;
}
async handle(ctx: HttpContext): Promise<void> {
const shouldContinue = await this.process(ctx);
if (shouldContinue && this.next) {
await this.next.handle(ctx);
}
}
protected abstract process(ctx: HttpContext): Promise<boolean>;
}
class AuthMiddleware extends MiddlewareHandler {
protected async process(ctx: HttpContext): Promise<boolean> {
if (!ctx.request.headers['authorization']) {
ctx.response.status = 401;
return false;
}
return true;
}
}
class MiddlewarePipeline {
private first: MiddlewareHandler | null = null;
private last: MiddlewareHandler | null = null;
use(handler: MiddlewareHandler): this {
if (!this.first) {
this.first = this.last = handler;
} else {
this.last!.setNext(handler);
this.last = handler;
}
return this;
}
}When to Use
| Situation | Recommendation |
|---|---|
| HTTP middlewares | ✅ Recommended |
| Layered validation | ✅ Recommended |
| Event processing | ✅ Recommended |
| Simple linear flow | ❌ Consider alternatives |
Conclusion
Chain of Responsibility allows building flexible pipelines where each handler has a clear responsibility.