REST API – API Versioning
APIs evolve. You add new fields, rename things, remove deprecated data, and improve the design. But thousands of clients already depend on your existing API. Change something without a plan, and you break all of them. API versioning is how you introduce change while keeping existing clients working.
What Is a Breaking Change?
A breaking change is any modification that causes existing clients to fail or behave incorrectly.
Breaking changes: ❌ Removing a field from the response ❌ Renaming a field (e.g., "name" → "fullName") ❌ Changing a field's data type (e.g., "price": 499 → "price": "499") ❌ Changing a required field to optional or vice versa ❌ Removing or renaming an endpoint Non-breaking changes (safe to add without a new version): ✅ Adding new optional fields to a response ✅ Adding a new optional query parameter ✅ Adding a new endpoint ✅ Adding new enum values to a field
The Three Versioning Strategies
Strategy 1: URL Path Versioning (Most Common)
The version appears in the URL: https://api.shop.com/v1/products https://api.shop.com/v2/products Diagram: Client A (old app) ──▶ /v1/products ──▶ Old response format Client B (new app) ──▶ /v2/products ──▶ New response format Both clients work simultaneously on the same server. ✅ Advantages: Easy to see, easy to test in a browser Clear and explicit — no guessing which version you are using ❌ Disadvantage: URL is supposed to identify a resource, not a version You may end up maintaining many versions simultaneously
Strategy 2: Header Versioning
The version goes in a custom request header: GET /products API-Version: 2 Or using the Accept header: GET /products Accept: application/vnd.shop.v2+json ✅ Advantages: Keeps URLs clean — same URL works for all versions Follows HTTP design principles more closely ❌ Disadvantage: Not visible in browser — harder to test and debug Clients must know to send the header
Strategy 3: Query Parameter Versioning
The version is a query parameter: GET /products?version=2 GET /products?api-version=2 ✅ Advantage: Easy to test in browser without tools ❌ Disadvantage: Clutters the URL Mixes version with business parameters like filters and sorting Least preferred approach
Comparing the Three Strategies
┌─────────────────────┬────────────┬──────────────┬──────────────────┐ │ Attribute │ URL Path │ Header │ Query Param │ ├─────────────────────┼────────────┼──────────────┼──────────────────┤ │ Visibility │ High │ Low │ Medium │ │ Browser testable │ Yes │ No │ Yes │ │ URL cleanliness │ Low │ High │ Medium │ │ Adoption │ Very high │ Medium │ Low │ │ REST purity │ Medium │ High │ Low │ └─────────────────────┴────────────┴──────────────┴──────────────────┘ Recommendation: Use URL path versioning (/v1, /v2). It is the most widely used and understood approach.
When to Create a New Version
Create v2 when: ✅ You need to rename a widely used field ✅ You are restructuring the entire response shape ✅ You are removing an endpoint or field clients rely on ✅ You are changing authentication mechanism Do NOT create v2 for: ❌ Adding a new optional field (just add it to v1) ❌ Adding a new endpoint (just add it to v1) ❌ Bug fixes that do not change the interface
Managing Multiple Versions
Version lifecycle: ┌────────────┬─────────────┬──────────────┬────────────────┐ │ v1 │ v2 │ v3 (latest) │ │ │ Deprecated│ Supported │ Current │ │ │ │ │ │ │ │ Sunset: │ Full │ Full │ │ │ Dec 2024 │ support │ support │ │ └────────────┴─────────────┴──────────────┴────────────────┘ Steps for deprecating a version: 1. Announce deprecation date at least 6-12 months in advance 2. Add a Deprecation header to v1 responses 3. Provide a migration guide to v2 4. Send reminder emails to API key holders 5. Sunset v1 on the announced date
Deprecation Headers
When a version is deprecated, warn clients in the response: Response headers from a deprecated endpoint: Deprecation: true Sunset: Sat, 31 Dec 2024 00:00:00 GMT Link: <https://api.shop.com/v2/products>; rel="successor-version" This tells automated tools and developers: - This endpoint will be shut down - When it will disappear - Where to go instead
Versioning a Real API
v1 response:
GET /v1/users/5
{
"name": "Priya Sharma",
"email": "priya@example.com"
}
v2 response (split name into first/last, add phone):
GET /v2/users/5
{
"firstName": "Priya",
"lastName": "Sharma",
"email": "priya@example.com",
"phone": "+91-9876543210"
}
Both versions run simultaneously.
Old apps use /v1. New apps use /v2.
Key Points
- Breaking changes require a new API version; additive changes do not
- URL path versioning (
/v1/,/v2/) is the most widely used strategy - Never delete an old version without giving clients time to migrate
- Use
DeprecationandSunsetheaders to signal upcoming removal - Provide a migration guide whenever you introduce a new version
