Your team is writing a style guide for an HTTP API. What do you specify for casing of path segments, casing of query parameter names, trailing slashes, and why?
answer
- scheme/host case-insensitive, path case-sensitive
- lowercase-hyphen path segments
- query names match JSON body casing
- /users vs /users/ = different URLs
- canonical form + 301, lint the OpenAPI
basics
~20 sPath segments: lowercase, hyphen-separated (/purchase-orders) because paths are case-sensitive and hyphens read well. Query parameter names: one convention API-wide, usually camelCase or snake_case matching the JSON body. Trailing slash: pick one form, redirect the other with 301.
solid answer
~50 sThree rules, each with a mechanical reason. **Path segments — lowercase with hyphens.** The host part of a URL is case-insensitive but the path is case-sensitive, so `/PurchaseOrders` and `/purchaseorders` are different resources; a lowercase-only rule removes a whole class of 404s that look like server bugs. Hyphens are the web-wide separator and stay readable in logs and CLIs. **Query parameter names — match the body.** Query names are free-form, so the only thing that matters is one convention API-wide; picking the same casing your JSON payloads use (`pageSize` or `page_size`) means clients never switch mental models mid-request. **Trailing slashes — canonicalise.** `/users` and `/users/` are formally distinct URLs and frameworks disagree. Choose the no-slash form, enforce it in routing, and answer the other with `301` to the canonical form so caches, logs, and metrics do not split one resource into two keys.
go deeper
Know the concrete rules: lowercase hyphenated paths, one consistent style for query names, one trailing-slash form.
Give the reason behind each rule — path case sensitivity, separator readability, and duplicate cache/log keys from slash variants.
Talk about canonicalisation as an operational concern: cache keys, rate-limit buckets, analytics, relative-reference resolution, and enforcing rules via spec linting.
Position it as governance across many teams — a linted style guide in CI, a migration path for existing non-conforming endpoints, and the cost of URL churn to client owners.
## Why casing is a correctness issue, not taste RFC 3986 makes the **scheme and host case-insensitive** and leaves everything after them — path, query, fragment — **case-sensitive**. `https://API.Example.com` and `https://api.example.com` are the same origin; `/PurchaseOrders` and `/purchaseorders` are not the same resource. In practice some servers and frameworks normalise case and some do not, so an API with mixed-case paths produces failures that depend on which client, proxy, or generated SDK wrote the URL. A flat rule — path segments are lowercase — removes the ambiguity entirely. The separator choice between `purchase-orders`, `purchase_orders`, and `purchaseOrders` is softer, but hyphen is the long-standing web convention: it survives underlining in UIs (underscores can visually disappear), it is what humans type, and it avoids re-introducing case sensitivity through camelCase. Note that this rule is about **path segments**, not about JSON field names. ## Query parameter names are a different namespace Query strings are opaque to HTTP itself — the standard says nothing about their internal syntax beyond allowed characters. Frameworks, form encodings, and client libraries all have their own habits, which is exactly why the rule has to come from your style guide rather than from the protocol. The usual advice is to make query parameter names match the casing of your JSON payload fields, because a client working with `pageSize` in a response body and `page_size` in a query string is guaranteed to get it wrong sometimes. Whatever you pick, apply it to every endpoint, including the standard ones like paging and sorting. ## Trailing slashes and canonical form `/users` and `/users/` differ by one character and, per the URI spec, identify different resources. Real behaviour varies: some routers treat them as equal, some 404, some redirect. The failure modes when you leave it undefined are subtle rather than loud — cache entries duplicated under two keys, analytics splitting one endpoint into two rows, relative-reference resolution changing (a relative link resolved against `/users` drops the last segment, while against `/users/` it appends), and rate limits keyed by path counting each form separately. The fix is to declare one **canonical** form, almost always without the trailing slash, enforce it in the router, and respond to the non-canonical form with `301 Moved Permanently` pointing at the canonical URL. A permanent redirect is preferable to a silent internal alias because it teaches clients and caches the correct URL once, rather than accepting both forever. ## Other canonicalisation the guide should cover Since you are writing rules anyway, decide the neighbouring cases at the same time: no file extensions in paths (format is negotiated with `Accept`), no duplicated separators (`//`), a defined position for the version segment if you use one, and whether query parameter ordering is significant for cache keys — it usually is not for your server but it *is* for naive caches, so clients that build URLs deterministically get better hit rates. ## Enforcement A style guide nobody checks decays within a quarter. These rules are all mechanically checkable against an OpenAPI document — a linter that rejects uppercase or underscored path segments, trailing slashes, and extensions in paths keeps the surface consistent as the number of contributing teams grows.
- Why prefer a 301 redirect for the non-canonical trailing-slash form instead of just routing both forms to the same handler?Accepting both forever means two cache keys, two log lines, and two rate-limit buckets for one resource, and clients never learn which form is intended. A 301 tells caches and well-behaved clients to use the canonical URL from then on, so the duplication converges away instead of persisting.
saying these in an interview costs you the question
- Saying URLs are case-insensitive because domain names are
- Applying the hyphen rule to JSON field names and query parameter names too
- Assuming every framework treats /users and /users/ identically
- Claiming query string syntax is defined by an RFC that mandates a casing style
- Writing the rules but never linting the spec, so drift returns