API Versioning
Evolve your API without breaking existing clients.
1The Restaurant Menu Analogy
API versioning allows you to make breaking changes while maintaining backward compatibility for existing clients. It's the contract between your API and its consumers.
2Versioning Strategies
URL Path Versioning
/api/v1/users, /api/v2/users- ✓ Explicit and visible
- ✓ Easy to test in browser
- ✓ Clear routing
- ✗ Not RESTful (resource URL changes)
- ✗ Harder to deprecate
Used by: Stripe, Twilio, GitHub
Query Parameter
/api/users?version=2- ✓ Optional (can default)
- ✓ URL stays same
- ✗ Easy to miss
- ✗ Caching complications
- ✗ Less discoverable
Used by: Google, Amazon (some APIs)
Header Versioning
Accept: application/vnd.api+json;version=2- ✓ Clean URLs
- ✓ Truly RESTful
- ✓ Flexible
- ✗ Hidden from URL
- ✗ Harder to test
- ✗ Requires header inspection
Used by: GitHub (Accept header)
Content Negotiation
Accept: application/vnd.company.v2+json- ✓ Most RESTful
- ✓ Fine-grained control
- ✗ Complex
- ✗ Less intuitive
Used by: GitHub API
3When to Version
Breaking Changes (Need Version)
- ✗Removing a field
- ✗Renaming a field
- ✗Changing data type
- ✗Removing an endpoint
- ✗Changing response structure
Non-Breaking (No Version Needed)
- ✓Adding optional field
- ✓Adding new endpoint
- ✓Adding optional parameter
- ✓Performance improvements
- ✓Bug fixes
4Deprecation Strategy
5Real-World Example: Stripe
Stripe's Approach
// Request with specific version
curl https://api.stripe.com/v1/charges \
-H "Stripe-Version: 2023-10-16"
// Response includes version info
{
"api_version": "2023-10-16",
"data": {...}
}
// Default: your account's pinned version
// Override per-request with headerStripe pins each account to a version at signup. You upgrade when ready. Breaking changes are opt-in.
6Best Practices
Use Semantic Versioning for Major Changes
v1, v2, v3 for breaking changes. Not v1.1, v1.2 for API versions.
Support At Least 2 Versions
Current and previous. Give clients time to migrate.
Document Changes Clearly
Changelog with breaking vs non-breaking changes. Migration guides.
Version from Day One
Start with /v1/. Adding versioning later is painful.
Default to Latest (Carefully)
Or pin to specific version. Stripe pins at signup, GitHub defaults to latest.
7Key Takeaways
?Quiz
1. Adding a new optional field to response. Do you need new version?
2. Which versioning is most explicit and testable?