Lesson 19 / 27
Running v1 and v2 Side by Side
See how two versions can coexist while v2 improves the response shape.
One data model, two representations
A common cause of a new version is a better representation. In the demo API, v1 returned a single name string; v2 splits it into first_name and last_name, which is a breaking change for clients that read name. The server keeps one internal model and two thin serialisers, so both versions are served from the same data and new features do not need to be built twice. v1 stays available, marked deprecated with a sunset date, while clients migrate to v2.
v1 (deprecated) and v2 responses, run
I ran this against a small real HTTP API built with only the Python standard library (full code in the case study). v1 returns name and adds Deprecation, Sunset and a Link to the successor version. v2 returns the split fields and no deprecation header (None).
# uses srv, base and call() from the runnable demo in the case study
s, h, b = call("GET", "/v1/items/1"); print(s, b, h.get("Deprecation"), h.get("Sunset")); print(h.get("Link"))
s, h, b = call("GET", "/v2/items/1"); print(s, b, h.get("Deprecation"))
Output:
200 {'id': 1, 'name': 'Asha Rao', 'plan': 'pro'} true Wed, 31 Dec 2026 23:59:59 GMT
</v2/items/1>; rel="successor-version"
200 {'id': 1, 'first_name': 'Asha', 'last_name': 'Rao', 'plan': 'pro'} NoneQuick check: Why keep one internal model for several API versions?
- It removes the need for tests
- It forces clients to upgrade
- Multiple models are always required
- Features and fixes are implemented once and exposed through version-specific serialisers
Answer
Features and fixes are implemented once and exposed through version-specific serialisers — Thin translation layers limit duplication while old and new shapes coexist.