This onion-shaped pattern isn't unique to these three frameworks — it turns up, wearing different vocabulary, in almost any language or framework built around a request/response cycle. Being able to name it on sight, in a codebase you've never opened before, is frequently the actual thing being tested when a résumé question turns into "so what happens if the client hits your API with a bad token?"
| Framework | Name for the pattern | Notes |
|---|---|---|
| Ruby on Rails / Rack | Rack middleware | Nearly identical shape to Django's — each layer wraps app.call(env) |
| Spring (Java) | Filters / Interceptors | Servlet Filters wrap the whole request; HandlerInterceptors hook into specific pre/post-controller points |
| NestJS | Middleware / Guards / Interceptors | Splits the general pipeline into three specialized stages — guards specifically decide "is this request even allowed to proceed," interceptors wrap and transform the response |
| ASGI (Python, e.g. FastAPI/Starlette) | ASGI middleware | Same wrapping shape as Django's WSGI middleware, built for an async request/response cycle instead |
If Fernwood's mobile team ever rebuilds Counter's offline-approval logic for an Electron kiosk app in NestJS, the guard/interceptor split is worth understanding rather than memorizing: a guard is answering the short-circuit question from earlier in this piece — let this through, or don't — while an interceptor answers the wrapping question — reshape what's going in or coming back out. NestJS simply gave those two questions their own dedicated types instead of leaving both bundled into one catch-all middleware function. Naming that correspondence out loud, in an interview or anywhere else, tends to land better than reciting five frameworks' worth of terminology from memory.