API Versioning Strategies
# CHAPTER 23
API Versioning Strategies
1. Introduction
Once an API is live and being used by mobile apps and external companies, you cannot simply change the rules. If you rename a database column fromfirstname to firstName, every mobile app relying on firstname will instantly crash. In Chapter 23, we will discuss API Versioning—the practice of managing "breaking changes" gracefully so older clients keep working while new clients get the latest features.
2. Learning Objectives
By the end of this chapter, you will be able to:- Define what constitutes a "Breaking Change" in an API.
-
Implement URL-based versioning (e.g.,
/v1/,/v2/).
- Understand Header-based versioning.
- Explain the concept of Backward Compatibility.
- Implement basic version routing in a PHP application.
3. Beginner-Friendly Explanation
Imagine a TV manufacturer. They release the "Model 1" remote control. Millions of people buy it. Later, they design a much better "Model 2" remote control. They don't sneak into everyone's house and destroy the Model 1 remotes. Instead, they support *both* remotes. If a customer uses Model 1, the TV responds one way. If a customer buys Model 2, the TV responds with new features.In APIs, "Model 1" is Version 1 (v1). When we make massive changes, we don't delete v1; we create v2 and run them side-by-side until everyone upgrades.
4. Real-World Examples
-
Twitter API: Look at Twitter's endpoints:
https://api.twitter.com/2/tweets. That/2/means they are on Version 2 of their entire architectural design.
-
Stripe API: Stripe uses date-based versioning passed in the headers. You send a header like
Stripe-Version: 2023-10-16, and Stripe transforms the response to match how the API worked on that specific date!
5. Detailed Code Examples
The most common and developer-friendly approach is URL Versioning. Let's adapt our PHPindex.php router to handle versions.
6. Request/Response Examples
By using URL versioning, developers can clearly see which version of the data contract they are subscribing to.Client A Request:
GET /api/v1/users/5
Response: {"firstname": "Jane", "lastname": "Doe"}
Client B Request:
GET /api/v2/users/5
Response: {"full_name": "Jane Doe"}
7. HTTP Examples
Another approach is Header Versioning (also called Content Negotiation Versioning). This keeps URLs perfectly clean but makes testing slightly harder.*Here, the client specifies they want version 2 inside the Accept header instead of the URL.*
8. JSON Examples
When deprecating an old version, it is good practice to include warning headers or metadata in the JSON response so developers know they need to upgrade soon.9. Best Practices
-
Version from Day 1: Always put
/v1/in your base URL from the very beginning (https://api.yourapp.com/v1/). If you don't, adding/v2/later creates a messy, inconsistent architecture.
-
Maintain Backward Compatibility: Do not increment to
v2for minor changes. Adding a *new* field to a JSON response is backward compatible (old apps just ignore the new field). Removing or renaming a field is a *breaking change* and requires a new version.
-
Deprecation Schedules: Never turn off
v1overnight. Give developers 6 to 12 months' notice via email and API headers before turning off an old version.
10. Common Mistakes
-
Creating a v2 for bug fixes: Versions should only change for structural data changes. Bug fixes and performance improvements should be applied directly to
v1.
-
Duplicating all code: When making
v2, don't copy/paste your entire codebase.v1andv2should share the same database and core models; only the *Controllers* (the formatting of the JSON) should differ.
11. Mini Exercises
-
1.
Determine if this is a breaking change: You have an endpoint
GET /products. You decide to add a new"stock_count": 50field to the JSON response.
v2 for this.)*
-
2.
Determine if this is a breaking change: You decide to change the
"price"field from a string"$10.00"to an integer1000(cents).
v2 for this).*
12. Coding Challenges
Challenge 1: Write a PHPif/else block that checks if the incoming header Accept-Version is set to 3. If it is, output {"format": "new"}, otherwise output {"format": "old"}.
13. MCQs with Answers
What is the most common and visible method for versioning a REST API?
Which of the following is considered a "Breaking Change"?
Why should you include /v1/ in your URLs from the very start of a project?
14. Interview Questions
- Q: Explain the difference between URL Versioning and Header Versioning. Which do you prefer and why?
- Q: Give three examples of "Breaking Changes" that would require bumping the API version.
-
Q: How do you handle the codebase when supporting both
v1andv2simultaneously without duplicating massive amounts of code?
15. FAQs
Q: How many versions should I maintain at once? A: Try to maintain no more than two (the current version and the immediate legacy version). Maintaining v1, v2, v3, and v4 simultaneously becomes an administrative and testing nightmare.16. Summary
In Chapter 23, we learned how to future-proof our APIs through Versioning. We defined what breaking changes are (renaming, deleting, or changing data types) and learned that adding new fields is perfectly safe. We explored URL versioning (/v1/), header versioning, and how to structure our PHP router to serve different JSON formats based on the requested version, ensuring mobile apps never crash unexpectedly.