In a server-side web framework, what ordered stages does one request pass through from route resolution to the written response?
answer
- in, then back out
- resolve before anything route-scoped runs
- binding sits between hooks and handler
- rendering turns a value into bytes
- failures divert, they do not continue
basics
~20 sOne dispatch runs in order: resolve the route, run pre-handler hooks, bind the request into handler inputs, invoke the handler, render what it returned, then unwind the post-handler hooks. A failure at any stage diverts to the error stage instead.
solid answer
~40 sA dispatch is an ordered pipeline, not one function call. The framework first **resolves the route** — method and path become a chosen handler plus any variables pulled out of the path. It then runs the **pre-handler hook chain** (authentication, correlation ids, logging, rate limiting), then **binds** the raw request into the handler's typed inputs: path variables, query values, headers, and a deserialized body. Only then is the **handler** invoked. What the handler returns goes through **rendering**, which turns a value into a status, response headers and bytes. Control then **unwinds back out** through the hooks that already ran, and the request's resources are released. Any stage that fails leaves the straight line and enters the **error stage**. Names differ across frameworks — filters, middleware, interceptors, phases — but the inbound-then-outbound shape is near-universal.
go deeper
Be able to recite the order out loud: resolve, hooks in, bind, handle, render, hooks out, with errors diverting to an error stage. That alone answers most screening versions of this question.
Explain why the order is forced — each stage needs the previous stage's output — and what each stage can still change. Name the inbound and outbound halves and say what information each half has.
Use the order to diagnose: a hook that sees no route metadata, a size check that fires too late, a header added after flush. Say which stage the symptom points at before touching a debugger.
Decide which responsibilities the platform owns as pipeline stages versus what each service writes itself, and accept the cost: a stage placed outermost is uniform but blind to route detail, while a route-scoped one sees everything and is easy to forget.
## What "dispatch" means Once a server has read and parsed an incoming HTTP message, something must decide **which** piece of application code runs and **what** gets written back. That decision, plus everything wrapped around it, is the **dispatch pipeline**: a fixed, ordered sequence of stages the framework runs for every request. The vocabulary differs between frameworks — filters, middleware, interceptors, plugins, phases — but the shape is stable, because each stage consumes what the previous one produced. You cannot bind a body to a handler's parameters before you know which handler was chosen, and you cannot render a result before there is one. A useful mental model is a funnel with a mirror at the bottom: the request travels **inward** through a series of stages, the handler sits at the centre, and the response travels **outward** through the same stages in reverse. ## The stages, in order 1. **Route resolution.** The request's method and path (sometimes also headers) are turned into a decision: this handler, plus the variables extracted from the path. If nothing matches, dispatch ends here — typically 404 — and nothing scoped to a route ever runs. 2. **Pre-handler hooks.** The inbound half of the hook chain: identity, correlation ids, request logging, rate limiting, opening a unit of work. Each element may pass the request on or stop it and produce a response itself. 3. **Binding.** Raw strings and bytes become the handler's typed inputs: path variables, query values, headers, and a body deserialized according to its declared content type. Conversion failures and, in most frameworks, declarative validation surface here — **before** the handler. 4. **Handler invocation.** Application code runs. It returns a value, writes to the response directly, or returns something that completes later if the framework supports asynchronous results. 5. **Rendering.** The returned value becomes a status code, response headers and a byte stream — serialization, content negotiation, template expansion, or a straight pass-through for a stream. 6. **Post-handler hooks.** The outbound half: the elements that already ran regain control, now able to observe the status and the elapsed time. 7. **Error stage.** Not a step on the straight line. Any stage that fails diverts here, and this stage produces a response of its own. After stage 7 the request's **lifetime** closes: per-request context is torn down, the body and any borrowed resources are released, and buffers may be recycled. ## Inbound half versus outbound half | | Inbound (stages 1-4) | Outbound (stages 5-6) | |---|---|---| | Knows | who is calling, what was asked for | what was answered, how long it took | | Can still change | the request, which handler runs, whether to proceed at all | the response, until its first bytes are flushed | | Typical work | authentication, quotas, parsing, starting a unit of work | metrics, access logs, adding response headers, cleanup | | Skipped when | an earlier element stops the request | its inbound half never ran | The asymmetry in the last row is where most confusion lives: the outbound half is not a separate list that always runs, it is the **return path** of the inbound half. An element that never got control on the way in has nothing to return from. ## Where frameworks differ Frameworks differ on three points, and it is worth knowing which model you are in rather than which framework does which. Some model hook elements as **wrappers** that explicitly call the next element and regain control when it returns, so inbound and outbound work live in one function; others let you register **separate before and after callbacks**, which run as two independent lists. Some expose **binding** as a stage with its own extension points; others fold it into the invocation step. And some run a globally mounted outermost chain *around* route resolution, so even unmatched requests pass through it, while anything scoped to a route necessarily runs after resolution. ## Why interviewers ask this Because ordering bugs are the classic trap, and they are diagnosed by knowing the order rather than by reading a stack trace: - A hook that reads the matched route's metadata sees nothing, because it was mounted outside route resolution. - A body-size check placed after binding never fires — binding has already read and materialised the body. - A handler's own error handling does not cover serialization of the value it returned, because rendering happens after the handler has returned. - A response header added in a post-handler hook is missing, because bytes were already flushed by then. All four are the same mistake: reasoning about the pipeline as a bag of features rather than as a sequence. Learn the sequence once and the diagnoses follow from it.
- Why does route resolution usually come before the hook chain rather than after it?Because hooks are commonly scoped to a route or a group of routes, the framework must know which route matched before it can decide which hooks apply. Resolving first also lets an unmatched path end cheaply without running per-route work. A globally mounted outermost chain can still wrap resolution itself — but anything route-scoped cannot.
- Is binding a stage of its own, or just part of invoking the handler?Conceptually it is its own stage: it reads the request model and produces typed inputs, and it can fail before a single line of handler code runs — which is why a malformed body yields a 400 with nothing in the handler's log. Some frameworks expose it with its own extension points; others fold it into the invocation step.
- Where does a response header added by a post-handler hook go if the body has already been streamed?Nowhere. Headers travel ahead of the body, so once the first bytes are flushed the status and header set are fixed and a later addition is silently dropped or raises an error. Work that must affect headers belongs on the inbound side or in the rendering step, not on the way back out.
saying these in an interview costs you the question
- Thinks the handler is the first thing the framework runs for a request.
- Assumes hooks only run inbound and never regain control on the way out.
- Believes a handler's own error handling covers serialization of what it returned.
- Says binding failures reach the handler as null or empty arguments.
- Treats the error stage as just another element in the normal chain.