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

nextnextAuthhandler 1Rate limithandler 2Controllerhandler 3
Each handler can stop or forward.

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.

More General articles