skip to content

Parameter Sources & Precedence

Binding handler arguments from path, query, headers, cookies, form fields and body, and which source wins on a name clash. Interviewers ask it because inferred sources hide bugs until a bad request.

on this pageshow

questions

5

In a server-side web framework, which parts of an HTTP request can a handler parameter be bound from?

level: juniorimportance: must knowfreq 72%

answer

  1. a request is several bags, not one
  2. path, query, header, cookie, form, body
  3. plus framework context values
  4. a marker states the source
  5. otherwise name and type infer it

basics

~20 s

Handler parameters bind from captured path segments, the query string, headers, cookies, form fields, or the parsed body. The framework picks the source from an explicit marker on the parameter, or infers it from the parameter's name and type.

solid answer

~50 s

A request is not one bag of values but several, and binding is the step that turns them into typed handler arguments. The usual sources are the **path** segments captured by the route template, the **query string**, request **headers**, **cookies**, **form fields** from a key/value-encoded body, and the **body** parsed as a whole into one object. Most frameworks also bind non-input values the same way — the request object itself, or an attribute an earlier middleware stored on the request. Which source a parameter uses comes either from an explicit marker on the parameter that names the source (and usually the wire name), or, where the framework supports it, from inference: a name matching a route variable binds from the path, a scalar binds from query or form, a structured type binds from the body.

go deeper

for a junior

Be able to list the sources — path, query, header, cookie, form field, body — and say that a marker on the parameter names which one, otherwise the framework guesses from the name and type.

for a middle

Explain the inference rules and why they exist, and why header and cookie names normally have to be written out rather than inferred from a parameter name.

for a senior

Show you know which sources can be absent or duplicated on a request the router accepted, and that you design handler signatures so each value comes from exactly one stated place.

for a principal

Frame the handler signature as the service's request contract: the thing docs, tests and gateways read. Argue for conventions that keep it honest rather than for whichever spelling is shortest.

## What binding is A **handler** is the function the router calls once a request matches a route. **Binding** is the step in between: the framework reads the raw request, pulls values out of it, converts them to the types the handler declared, and calls the handler with them. Without binding, every handler would take one request object and dig values out by hand. With it, the handler's signature becomes a machine-readable statement of what the request must contain — which is also what documentation generators, validators and test helpers read. ## The sources a request offers - **Path segments** captured by the route template. The router matched the template to get here, so a captured segment is present by construction; it arrives as text. - **Query string** — the `name=value` pairs after `?`. Names may repeat, values are entirely client-controlled, and the whole string tends to appear in access logs, proxy logs and browser history. - **Headers** — names are case-insensitive and commonly contain hyphens, and a name may appear more than once or arrive comma-joined. - **Cookies** — technically one header, but almost always exposed as its own name-keyed source because the shape is different. - **Form fields** — a body encoded as key/value pairs (URL-encoded, or a multipart document). These are body bytes, yet they expose a query-like name/value surface, which is why many frameworks bind them with the same machinery as the query string. - **The body as a whole** — the payload parsed into one structured object and bound to a single parameter. - **Framework-supplied context** — the request, a response writer, the matched route information, the authenticated principal, or a value an earlier middleware stored in the request's attribute map. Not client input, but bound through the same mechanism. ## How a parameter is tied to a source Two mechanisms, and most frameworks ship both: 1. **An explicit marker** on the parameter states the source, and usually also the **wire name**, which matters because header and query names frequently cannot be spelled as an identifier in code. 2. **Inference**, when no marker is given. The typical rules are: the parameter's name matches a route-template variable, so bind from the **path**; the type is scalar, so bind from the **query** (or from form fields, in some frameworks, when the request carries an encoded body); the type is a structured object, so bind from the **body**; the type is one the framework owns, so inject the **context** value. Where both exist, an explicit marker takes precedence over inference — the marker is the statement, inference is the fallback. ## The sources are not interchangeable | Source | Name rules | Can repeat | Guaranteed present | |---|---|---|---| | Path | fixed by the route template | no | yes, if the route matched | | Query | any text, client-chosen | yes | no | | Header | case-insensitive, hyphenated | yes | no | | Cookie | name-keyed, from one header | rarely | no | | Form field | any text, client-chosen | yes | no, and needs an encoded body | | Body | the whole payload | n/a | no | Two consequences follow from that table. First, a **path** parameter is required by construction: if the segment were absent the template would not have matched, so the request would have ended as a 404 rather than reaching the handler. Every other source can be missing on a request the router happily accepted. Second, because query, header and form names are chosen by the client, the same logical name can arrive in several sources at once, which is what makes source precedence a real question rather than a formality. ## Traps worth knowing early - **Header and cookie names usually cannot be inferred** from a parameter name, because they are case-insensitive and hyphenated. These almost always need the wire name spelled out. - **The body is typically readable once.** Binding the whole body to one parameter and also asking for the raw bytes, or for individual form fields, may work, may fail, or may yield an empty second read depending on whether the framework buffers. - **"Present" and "non-empty" are different questions.** A query string ending in `q=` carries the name with an empty value, which is not the same as omitting it. - **Binding is not validation.** It gets a well-typed value into the handler; whether that value is allowed is a separate check the handler or a validation layer still owes.

  • Why can a path parameter be treated as always present while a query parameter cannot?
    The route template is what matched the request. If the segment the template captures had not been there, the route would not have matched and the request would have ended as a 404 instead of reaching the handler. A query parameter takes no part in that decision, so the router admits requests that omit it entirely.
  • Why do form fields and the parsed body count as two sources when both come from the body bytes?
    They are two readings of the same bytes. A key/value-encoded body exposes a flat name/value surface that can be bound one field at a time, like the query string. Binding the body as a whole hands the entire payload to one parameter as a structured object. Asking for both in one handler can fail, because the payload is often readable only once.
  • Where do values that are not in the request at all — the current user, a request id — come from?
    From a per-request context: an attribute map that middleware writes before the handler runs, or a framework-owned type the binder recognises. It uses the same binding machinery, so the handler signature stays uniform, but the value was computed by earlier layers rather than parsed from the wire.

A parcel arrives with an address on the label, a note tucked under the tape, a sticker on the lid and a letter inside. Same courier, four places to look — and you have to say which one you meant.

saying these in an interview costs you the question

  • Treating the request as one flat map of parameters with no sources
  • Assuming a header can be bound by matching the parameter's name
  • Believing a bound value has been validated just because it converted
  • Thinking a query parameter is as guaranteed to be present as a path segment
  • Reading the body twice in one handler and expecting the second read to work
open as a page

How does an explicit source marker on a handler parameter differ from letting a framework infer the source?

level: middleimportance: must knowfreq 60%

basics

~20 s

An explicit marker states the source and the wire name, so binding is fixed by the declaration. Inference derives it from the parameter's name and type — shorter, but it changes silently when a name, type or route template changes.

open as a page

What should a framework do when a handler declares a parameter the incoming request does not carry?

level: middleimportance: should knowfreq 55%

basics

~20 s

A missing required value should fail with 400, naming the parameter and its source; a missing optional one should reach the handler as an explicit absence. A path capture cannot be missing: a non-matching template gives 404 instead.

open as a page

A request carries the same parameter name in the path, the query string and the form body — which value reaches the handler, and why is that risky?

level: seniorimportance: should knowfreq 52%

basics

~20 s

No cross-framework standard exists: some order the sources, others merge query and form into one map where one silently overwrites the other. The danger is two layers reading different copies of the name and disagreeing.

open as a page

When would you let a handler accept the same value from more than one request source, and how would you govern it?

level: principalimportance: should knowfreq 38%

basics

~20 s

Only for a value with no security or billing weight, where a client genuinely cannot send the canonical source. Govern it by naming one canonical source, folding the alias into it early in one place, and rejecting conflicting copies.

open as a page