- rtshkmr's digital garden/
- References/
- Architecture Design Basics/
- Pattern Taxonomy/
- Communication & API Design/
- API Versioning Strategies/
API Versioning Strategies
Table of Contents
🟠P1 — how you evolve public APIs without breaking consumers
Problem #
APIs evolve. Consumers depend on existing behaviour. Breaking changes break trust (and integrations). You need a strategy to evolve while maintaining backward compatibility.
Approaches #
| Strategy | Mechanism | Pros | Cons |
|---|---|---|---|
| URL versioning | /v1/users, /v2/users | Explicit, easy to understand | URL proliferation |
| Header versioning | Accept: application/v2+json | Clean URLs | Hidden, harder to discover |
| Query param | /users?version=2 | Simple | Feels hacky |
| Content negotiation | MIME types | RESTful | Complex, rarely used well |
| Additive-only | Never remove, only add fields | No versions needed | Schema bloat over time |
Instinct #
Stripe’s approach is instructive: they use dated API versions (2023-10-16) with an additive-only default. Each version is a set of “changes” applied on top of the previous one. This avoids the v1/v2/v3 proliferation problem while giving consumers stability. Stripe’s API versioning docs and engineering blog post describe this approach in detail.
The key insight: version the behaviour, not the URL.
For internal services, prefer additive-only changes + schema evolution (Protobuf field numbers). Versioning is a client-facing concern.
References #
- APIs as Infrastructure: Future-proofing Stripe with Versioning — Stripe Engineering
- API Versioning Has No “Right Way” — APIs You Won’t Hate
DDIA 2e Reference #
- Chapter 4: Schema evolution, forward/backward compatibility