CodeOath
← All posts
Architecture & Patterns50 min total · 13 parts

Middleware Pipelines Compared: ASP.NET Core, Express.js, and Django

Part 8 of 13 · ~2 min

Short-Circuiting: When Not Reaching the Handler Is the Feature

Answer a request early — before it's ever handed to whatever's registered further down, approveReturn included — and you've short-circuited it. Nearly every piece of access control or caching logic Counter runs is built on exactly that move:

  • Authentication rejects an associate with no valid session at 401, before anything about the request's content is even considered.
  • Authorization rejects Marcus specifically — logged in, but not a shift lead — attempting to approve a $980 return, at 403. The two rejections aren't interchangeable: 401 fires because the request never established an identity in the first place; 403 fires once identity is settled and the decision goes against you anyway.
  • Rate limiting matters more here than it usually does, because of what a retry actually risks: the POS tablets at checkout run on flaky in-store wifi, and a tablet that doesn't see a response in time will retry the same approval POST. Without a short-circuit on repeated identical requests, that's not just wasted work — it's a real risk of refunding the same $1,140 return to Ridgeline Pay twice. Counter short-circuits a repeated request with the same idempotency key at 429 (or replays the first response) rather than letting it reach approveReturn a second time.
  • Caching answers a regional manager's GET /returns/4471 from a short-lived cache when Dana's dashboard polls it every few seconds, instead of hitting Postgres on every single poll.
  • CORS preflight answers the browser's own OPTIONS request directly. Counter's associate-facing SPA runs at counter.fernwood-ops.com, calling an API at api.fernwood-ops.com — a different origin — so every non-trivial request gets a preflight OPTIONS first, and an early-registered middleware answers it on the spot, with no route ever getting a look at it.

What ties those four together: a pipeline where every function always calls next(), no exceptions, isn't guarding anything at all — it's just a sequence of observers watching a request pass through. Actually guarding something expensive or sensitive requires an if somewhere in the chain, a spot where a request can be stopped rather than merely noted. That same if is, concretely, the one thing standing between a flaky-wifi retry and Ridgeline Pay getting asked to refund the same boots a second time.