API Style & Pattern Comparisons
Side-by-side trade-offs. Neither column wins — the consumer environment, the data shape and the operational budget decide.
URI versioning (/v1/) vs Header / media-type versioning
The version in the path, visible in every log line and curl command vs the version negotiated in headers, keeping one URI per resource — a fight about visibility vs purity that matters less than what "version" promises.
A public API where discoverability wins: partners paste URLs into browsers, logs and dashboards show versions for free.
Versions are really per-endpoint or per-field — a global /v2/ forces a big-bang migration for one changed resource.
Zero ambiguity: the version is in every URL, log, cache key and bug report; routing v1 and v2 to different backends is trivial.
/v2/ ships as a marketing event, forks the codebase, and /v1/ lives forever because nobody funded the migration.
Parallel URL trees to route, document and test; clients hardcode paths and migrations mean touching every call site.
Resource identity must stay stable across versions — links, caches and HATEOAS-ish clients shouldn't break on a version bump.
Your consumers are scripts and low-code tools that struggle to set headers; the invisible version becomes invisible support load.
One URI per resource; versions can be negotiated per request; date-based pinning (a la Stripe) layers on cleanly.
A missing header silently defaults to an old version, and caches ignore Vary — serving v1 bodies to v2 clients.
Header-aware caching (Vary), version plumbed through tracing and logs by hand, and support tickets that omit the version entirely.
| Dimension | URI versioning (/v1/) | Header / media-type versioning |
|---|---|---|
| Visibility | In every URL, log and screenshot | Hidden in headers; must be surfaced deliberately |
| Routing & rollout | Path-based routing at the gateway — trivial | Header inspection at the routing layer |
| Resource identity | /v1/users/42 and /v2/users/42 are different URIs | One URI; the representation is negotiated |
| Cache behavior | Version is naturally part of the cache key | Depends on Vary being honored end to end |
| Granularity | Whole-API version steps | Per-request, per-resource or date-based pinning |