Chain of Responsibility Design Pattern Explained
Chain of Responsibility passes a request along a chain of handlers, where each handler decides either to process the request or pass it to the next handler.
Published November 13, 2026
Chain of Responsibility passes a request along a chain of handlers; each decides to handle it or pass it on. It decouples the sender from the specific handler.
The concept
Handlers link to the next one. A request travels until someone handles it (or the chain ends).
Web middleware, event bubbling in the DOM and support-ticket escalation are all chains.
Pass it along
Practical examples
Handlers
const chain = (...hs) => (req) => hs.reduceRight((next, h) => () => h(req, next), () => 'unhandled')()
const auth = (r, next) => (r.user ? next() : '401')
const limit = (r, next) => (r.count < 5 ? next() : '429')
const app = (r) => 'ok'
chain(auth, limit, app)({ user: 1, count: 2 })Express middleware
app.use(auth); app.use(limiter); app.get('/', handler)DOM bubbling
list.addEventListener('click', (e) => { if (e.target.matches('li')) pick(e.target) })Common mistakes
- Requests falling off the end unhandled.
- Hard-to-trace chains with no logging.
- Order dependence not documented.
Key takeaways
- Handlers pass requests along.
- Sender is decoupled.
- Define the fallback.
FAQ
Is middleware this pattern?
Yes, each middleware chooses to continue or respond.
Can multiple handlers act?
Yes, variants let every handler process before passing on.