Scalability & Architecture Patterns

API Versioning & Evolution

APIs must change without breaking every existing client — versioning strategy decides whether that happens through URL/header negotiation, additive-only schema evolution, or a deprecation policy with a real deadline.
  • URL versioning (/v1/orders), header versioning (Accept: application/vnd.api+json;version=2), and additive-only evolution are the three common strategies, each with different client-visibility tradeoffs
  • Backward-compatible ("additive") changes — new optional fields, new endpoints — do not need a version bump; removing or renaming a field, or changing its meaning, does
  • A deprecation policy needs three things to be real: an announcement, a sunset date, and telemetry on who is still calling the old version
  • Consumer-driven contract testing — each client publishes what it actually uses — lets a provider evolve a schema safely without knowing every client's exact code
  • Running multiple API versions simultaneously multiplies operational and testing surface — every version alive is a version someone has to keep working
  • Semantic versioning communicates intent, but most internal API version bumps are avoidable entirely by designing for additive evolution from the start
Versioning strategies
URL versioningHeader versioningAdditive-only
Client visibilityobvious in the URLhidden in a headerno version at all
Cachingcache-friendly — distinct URLsharder — same URL, different responsecache-friendly
When it worksany breaking changeany breaking changeonly additive changes
Evolving a response type additively
public record OrderResponse(
    String id,
    BigDecimal total,
    String currency,            // added later — old clients ignoring unknown fields still work
    List<String> discountCodes  // added later, defaults to empty — never remove a field, only add
) {}
Sources
  • Web Scalability for Startup EngineersCh. — API Design for Scale
  • System Design Interview – An Insider's GuideCh. — API Design Considerations