Best Practices

API Versioning

Manage API changes gracefully with versioning strategies, backward compatibility, and deprecation policies.

Why Version Your API?

Evolution Without Breaking

Add new features and fix issues without breaking existing integrations.

Introduce new endpoints
Change response formats
Modify authentication
Update business logic
Controlled Migration

Give clients time to update at their own pace without forcing immediate changes.

Gradual migration timeline
Test new version alongside old
Monitor adoption rates
Deprecate with notice

Versioning Strategies

1. URL Path Versioning (Recommended)

Include version number in the URL path. Most visible and explicit approach.

javascript
Pros: Clear, cacheable, easy to route and test
Cons: Version in every URL, potential code duplication
2. Header Versioning

Specify version in request headers using Accept or custom header.

javascript
Pros: Clean URLs, follows REST principles
Cons: Hidden, harder to test, caching complexity
3. Query Parameter Versioning

Include version as query parameter. Not recommended as primary strategy.

javascript
Pros: Easy to implement and test
Cons: Mixes versioning with filtering, inconsistent
4. Subdomain Versioning

Use different subdomains for each version. Useful for major rewrites.

http
Pros: Complete separation, independent deployment
Cons: Infrastructure overhead, CORS complexity

Version Numbering

Semantic Versioning (Major.Minor.Patch)
plaintext
MAJOR (1.x.x → 2.x.x)

Breaking changes - incompatible with previous version

  • Changed response structure
  • Removed endpoints or fields
  • Modified authentication
  • Changed required parameters
MINOR (x.1.x → x.2.x)

New features - backward compatible

  • New endpoints
  • Optional parameters
  • Additional response fields
  • New functionality
PATCH (x.x.1 → x.x.2)

Bug fixes - backward compatible

  • Error corrections
  • Performance improvements
  • Security patches
Simple Major Versioning (Recommended for APIs)

Use only major version numbers for API URLs to keep them simple and stable.

plaintext

Backward Compatibility

Making Non-Breaking Changes

✅ Safe (Non-Breaking) Changes

Add optional parameters
http
Add new response fields
json
Add new endpoints
http
Add new HTTP methods to existing endpoints
Make required fields optional

❌ Breaking Changes (Require New Version)

Remove or rename fields
json
Change response format
json
Make optional parameters required
Change data types
Remove or rename endpoints
Change authentication method

Deprecation Policy

Deprecation Process
javascript
Deprecation Timeline
Day 0
Release v2

New version available, v1 still fully supported

Month 1
Announce Deprecation

Add deprecation headers, update docs, email clients

Month 3
Migration Period

Clients migrate to v2, monitor usage drop

Month 6
Sunset v1

Remove v1, return 410 Gone for old endpoints

Sunset Response
json

Version Migration Guide

Example Migration Documentation
bash
Versioning Best Practices
Use URL path versioning: /v1/users is clearest and most cache-friendly
Version from day one: Start with /v1 even for initial release
Use major version numbers only: /v1, /v2, /v3 (not /v1.2.3)
Maintain backward compatibility: Add features without breaking existing clients
Document breaking changes: Clear migration guides for each version
Announce deprecation early: Give 6+ months notice before sunset
Use deprecation headers: Sunset, Deprecation, Link headers
Monitor version usage: Track adoption and notify active users
Support multiple versions: Keep 2-3 versions active during migration
Return 410 Gone after sunset: Not 404, to indicate intentional removal