Microservices API Versioning
Services change over time. New fields appear, old fields disappear, and rules shift. Other services and mobile apps depend on the current shape of every API, so a careless change can break them overnight. API versioning gives each change a label and lets old and new consumers coexist.
Layman Explanation
Imagine a restaurant that updates its menu. Regular guests still hold printed copies of the old menu and order dishes by the old names. A smart restaurant keeps serving the old dishes for a while, publishes the new menu, and retires the old one only after guests have switched. API versioning follows the same courtesy.
Breaking vs Non-Breaking Changes
Safe Changes
- Adding a new optional field to a response.
- Adding a new endpoint.
- Adding an optional request parameter.
Breaking Changes
- Removing or renaming a field.
- Changing a field type, such as number to text.
- Making an optional parameter required.
- Changing the meaning of a status code.
Safe changes need no new version. Breaking changes demand one.
Versioning Styles
URL Path Versioning
GET /v1/orders/501 GET /v2/orders/501
The version sits in the address. Beginners find it easy to see, test, and cache.
Header Versioning
GET /orders/501 Accept: application/vnd.shop.v2+json
The address stays clean and the version travels in a header. Tools need slightly more setup to test it.
Query Parameter Versioning
GET /orders/501?version=2
The version rides along as a parameter. Simple to use, though easy to forget.
Diagram: Two Versions Running Together
Old mobile app ----> /v1/orders ----+
| +------------------+
+------> | Orders service |
| | v1 adapter |
New mobile app ----> /v2/orders ----+ | v2 logic (core) |
+------------------+
A thin adapter translates the v1 shape into the core logic. Maintaining a single core avoids copying business rules into two code bases.
Example: Splitting a Name Field
Version 1 returns one field called name with the value "Asha Verma". Version 2 returns firstName and lastName. Renaming breaks every v1 client, so the team publishes v2 and keeps v1 alive.
v1 response: { "name": "Asha Verma" }
v2 response: { "firstName": "Asha", "lastName": "Verma" }
Retiring an Old Version
Follow a steady routine so consumers never feel surprised:
- Announce the retirement date weeks or months ahead.
- Mark responses with a deprecation header that names the end date.
- Track which clients still call the old version.
- Contact the owners of remaining clients directly.
- Switch the old version off on the announced date.
Consumer-Driven Contracts
Each consumer writes down the fields it truly uses. The provider runs those contracts as automated checks before every release. A failing check reveals a breaking change before any customer sees it.
Good Habits
- Prefer additive changes whenever possible.
- Version the whole API, not individual fields.
- Limit the number of live versions to two or three.
- Document every version with a clear change log.
Communicating Changes
A change log builds trust. Each entry names the version, the release date, and the exact fields that changed. Developers who consume the API subscribe to the log through email or a feed. Clear notes cut support questions and speed up upgrades across teams.
Key Takeaways
Versioning protects consumers from surprise. Choose one style, keep changes additive, run old and new versions side by side, and retire versions with clear notice.
