API Versioning
API Design
Visual Representation
What is it?
π± Think of it like phone updates:
When Apple releases iOS 18, they don't kill iOS 17 immediately. Millions of older iPhones still run iOS 17. Both versions coexist. Over time, older versions are deprecated (no longer supported).
API Versioning is the same β when you change your API (add fields, rename endpoints, change response format), you don't break ALL existing apps/clients overnight. You release a NEW version (v2) while keeping the OLD version (v1) running. Old apps keep working; new apps use the better version.
Without versioning: you change the API response format on Monday β every mobile app in production crashes because they expect the OLD format β users give 1-star reviews β disaster.
π‘ Simple Summary: API versioning lets you evolve your API without breaking existing clients. Old version keeps working while new version adds improvements.
How it works β Like you're watching it happen
The problem API versioning solves:
- Keep /v1/users returning OLD format (user_name, created)
- Launch /v2/users returning NEW format (username, created_at)
- Notify developers: "V1 deprecated, V2 available, V1 shutdown in 6 months"
- Apps migrate at their own pace. No one breaks. β
Where to put the version:
β But wait β GraphQL claims it doesn't need versioning. How?
GraphQL is additive β you ADD new fields without removing old ones. Old queries that ask for old fields still work. New queries can ask for new fields. Since the client specifies exactly what it wants, adding fields doesn't break anyone. REST can't do this easily because the server decides the response shape. That said, even GraphQL eventually needs to deprecate fields, which is its form of "versioning."
Why should you care? (Interview perspective)
Key Things to Remember
Real Examples You Use Daily
π³ Stripe β Uses date-based versioning (2023-08-16, 2024-01-15). Each API key is pinned to a version. New features require opting into a newer version. You upgrade at your own pace. This is the gold standard.
π¦ Twitter β URL-based: /1.1/tweets/search vs /2/tweets/search. V2 is completely redesigned. V1.1 ran for YEARS after V2 launched.
πΊοΈ Google Maps β /maps/api/place/v1/... Different versions for different feature sets. Old versions deprecated with clear timelines.
π± Mobile apps β When Instagram changes their API, they must keep old versions running because millions of phones have OLD app versions that won't update for months. API versioning gives them time.
Common Mistakes in Interviews
β Saying "just update the API and tell clients to upgrade" β You CANNOT force millions of mobile apps to update simultaneously. Some users never update! Versioning gives a graceful migration path.
β Versioning every minor change β Adding an optional field? NOT a new version. Only version on BREAKING changes. Over-versioning creates maintenance burden.
β Not having a deprecation plan β "We'll keep v1 running forever." No! That's unbounded maintenance cost. Set clear sunset dates: "V1 supported until December 2025."
β Forgetting about mobile apps β Web apps can update instantly (deploy new frontend). Mobile apps are installed on user devices β old versions persist for months/years. This is the PRIMARY reason API versioning exists.
β Making backward-incompatible changes without realizing β Changing a field from string to integer, removing a field "nobody uses" (someone always uses it), or changing error format β all breaking changes that need a new version.
π― Interview One-Liner
"I'd version the API in the URL path (/v1, /v2) for discoverability, only bump versions for breaking changes, maintain a clear deprecation policy with Sunset headers, and ensure backward compatibility by adding new fields as optional rather than modifying or removing existing ones."
Interview Q&A
Q: URL versioning vs header versioning β trade-offs?
URL (/v1/users): visible, easy to debug (you see the version in browser/logs), simple routing (nginx routes /v1/* to old service, /v2/* to new). But "pollutes" the URL (purists say version isn't a resource). Header (Accept: application/vnd.api.v2+json): clean URLs, but hidden (harder to debug, share, and cache since URLs look identical). Industry standard: URL versioning wins for public APIs due to simplicity.
Q: What constitutes a "breaking change" in an API?
Changes that break existing clients: (1) Removing a field from response, (2) Renaming a field, (3) Changing a field's type (string β integer), (4) Changing the URL pattern, (5) Making a previously optional field required, (6) Changing error response format, (7) Changing authentication mechanism. NON-breaking: adding new optional fields, adding new endpoints, adding new optional query parameters.
Q: How does Stripe handle API versioning?
Date-based versions (2023-08-16). Each account is pinned to the version it was created with. Stripe transforms responses internally β new code, but response is transformed to match the customer's pinned version. Customer can upgrade by changing their pinned version. This is elegant: one codebase, many version "views." New features require newer versions.
Q: How would you sunset an old API version?
Timeline: (1) Announce deprecation 6-12 months before shutdown. (2) Add Sunset header to all V1 responses. (3) Send emails to V1 API key users. (4) Add deprecation warnings to V1 responses. (5) Track V1 usage β contact remaining heavy users directly. (6) Return 410 Gone + migration docs after sunset date. (7) Never surprise-kill β give at least 3 warnings + final deadline extension if usage is still high.
Q: You're building a mobile-first app. How does versioning help?
Mobile apps installed on phones can't be force-updated. If v1.0 of your app expects API format X, but you change the API to format Y β every user who hasn't updated their app sees errors. With versioning: app v1.0 calls /api/v1. App v2.0 calls /api/v2. Both work simultaneously. You can sunset /api/v1 only after 95%+ of users have updated (track via version analytics).
Quick Quiz
1/5You rename a field from "user_name" to "username" in your API response. 1000 existing apps break. What should you have done?