skip to content

Which requests does a hook attached before routing run for that a route-scoped hook never sees?

level: middleimportance: should knowfreq 54%

answer

  1. route selection is the hinge
  2. unrouted traffic exists and matters
  3. 404 and 405 never enter a route chain
  4. count everything or count only matches
  5. short-circuit before the hinge skips scopes

basics

~20 s

Everything the server accepts but never routes: paths matching no route, methods the matched path does not support, requests rejected for a malformed line or oversized body, framework-handled redirects and preflight replies, and anything a wider hook answered before routing happened.

solid answer

~50 s

A hook attached ahead of route selection is in the chain for every accepted request, so it also runs for the population that never reaches a handler: a path matching no route and ending as `404`, a method the path does not support ending as `405`, a request rejected because the line or body was unacceptable, a trailing-slash or case redirect the framework answers itself, and a preflight `OPTIONS` that a wider hook completes. A route-scoped hook is spliced in only once a route has been chosen, so none of those ever enter it. The practical consequence is that anything which must count or constrain *all* traffic — total request counts, per-address limits, a correlation identifier on every response — has to live before routing, because the traffic it cares about most is often exactly the traffic that never matches.

go deeper

for a junior

Remember that a request can be answered without any route matching, and that hooks tied to a route are absent for those responses. A 404 is still a request the server handled.

for a middle

Be able to list the unrouted population concretely: no match, unsupported method, early rejection, framework redirect, preflight, and short-circuit before the hinge.

for a senior

Show what it means operationally: which metrics under-report, which limits miss hostile traffic, which response headers go missing, and how you would diagnose a scoped hook that appears not to run.

for a principal

Decide the policy for a fleet: what every response must carry regardless of routing, what is allowed to cost anything before the hinge, and how services prove they comply.

Request handling has a hinge in it: **route selection**. Before the hinge, the framework knows only what arrived — a method, a target, headers, and a body it may not have read. After the hinge, it knows which route matched and which handler it is about to call. Where a hook is attached relative to that hinge decides which *population* of requests it is part of, and that is a question of scope rather than of visibility. ## The population that never reaches a route Every server accepts requests it does not route. A hook attached before routing is in the chain for all of them: - **No route matches the target.** The request ends as `404`, and no route-scoped chain exists to run. - **The target matches but the method does not.** The framework answers `405`, typically without entering any route's chain. - **The request is rejected early.** A malformed request line, a header block or body beyond a configured limit, an unsupported transfer encoding: the response is produced before routing was ever attempted. - **The framework answers by itself.** A redirect for a trailing slash or a case difference, a preflight `OPTIONS` completed by a cross-origin hook, a static asset served from a file tree that is not part of the route table. - **An earlier hook short-circuits.** Anything that responds without delegating ends the request before the hinge, so everything scoped to a route is skipped. | Situation | Pre-routing hook | Group hook | Per-route hook | |---|---|---|---| | Target matches no route (`404`) | Runs | Skipped | Skipped | | Method not supported (`405`) | Runs | Usually skipped | Skipped | | Framework-generated redirect | Runs | Skipped | Skipped | | Rejected before routing | Runs | Skipped | Skipped | | Normal matched request | Runs | Runs if in group | Runs if that route | The table has a caveat worth stating out loud: frameworks differ on where a method mismatch is decided. Some resolve the target first and reject the method afterwards, deep enough that a scope attached to that target may already be active; others treat method and target as one matching step, so nothing scoped runs. When it matters, the honest answer in an interview is to name both possibilities and say you would verify it for the framework at hand. ## Why the distinction is load-bearing The unrouted population is not an edge case; it is where several important signals live. 1. **Completeness of measurement.** A count of requests that only sees matched ones under-reports exactly during the incidents you care about — a client hammering a path that was renamed, a scanner walking the surface, a deploy that dropped a route. 2. **Constraints that must cover strangers.** A limit intended to stop an unknown caller flooding the server has to apply to traffic addressed to nothing at all, which means it cannot be scoped to routes. 3. **Guaranteed response properties.** If every response is supposed to carry a correlation identifier or a baseline security header, then `404` and `405` responses need it too, and only a pre-routing attachment covers them. 4. **Cost.** The converse is the reason not to put everything there: a pre-routing hook pays its cost on traffic no handler will ever accept, including hostile traffic. Anything expensive that only matters for real handlers belongs after the hinge. ## Reasoning about it without the framework's documentation Two questions settle most cases. First, *can this hook's work be expressed without knowing which route matched?* If it needs the route's identity, it cannot run before the hinge at all. Second, *is a request that matches nothing still interesting to this hook?* If yes, it must run before the hinge, even if it would also like the route's identity — in which case the usual resolution is two hooks, a thin one before routing and the substantive one after. A third consideration is short-circuiting: the earlier a hook sits, the more of the pipeline it can prevent, which is why cheap rejections are placed early and why a hook that responds before the hinge silently removes every scoped hook behind it from that request. When someone reports that a route-scoped hook "did not run", the first thing to check is whether the request ever reached routing at all.

  • Why does a limit meant to stop an unknown flooding caller have to sit before routing?
    Because the flood is frequently addressed to nothing that exists — a renamed path, a probe list, a scanner. Traffic that matches no route never enters a route-scoped chain, so a scoped limit would watch the one population that is behaving and ignore the one that is not.
  • What is the argument against putting everything before routing?
    Cost and blindness. A pre-routing hook pays on every accepted request, including traffic no handler will serve, and it cannot label its work with a route identity it does not have yet. Anything expensive, or anything that needs the matched route, belongs after the hinge.
  • A route-scoped hook seems not to have run for a request. What do you check first?
    Whether the request reached route selection at all. An earlier hook that responded without delegating, an early rejection, a framework-generated redirect, or simply no matching route all produce a response with no scoped hook in the chain, which looks identical from the outside.

saying these in an interview costs you the question

  • Assumes every accepted request eventually enters some route's chain
  • Counts traffic in a route-scoped hook and calls it total request volume
  • Expects a per-route hook to add its header to a 404 response
  • Puts an expensive check before routing where unrouted traffic also pays it
  • Forgets a short-circuit before routing removes every scoped hook from that request