Backwards Compatibility: API Evolution

Maintaining backwards compatibility is the discipline of allowing a system to change while ensuring that existing consumers continue to function without modification.

1. Defining Breaking Changes

A "Breaking Change" is any modification to the API contract that causes a consumer to fail.

* **Structural:** Removing a field, renaming a field, or changing a data type (e.g., `Int` to `String`).

* **Behavioral:** Changing the side effects (e.g., an endpoint that was read-only now triggers an email).

* **Semantic:** Changing the *meaning* of data (e.g., changing a currency field from USD to EUR without a unit change).

2. Versioning Strategies

| Strategy | Example | Pros | Cons |

| :--- | :--- | :--- | :--- |

| **URI** | `/v1/users` | Easy to route/cache. | Pollutes URI namespace. |

| **Header** | `Accept-Version: 2` | Clean URIs. | Harder for browser testing. |

| **Media Type** | `Accept: application/vnd.v2+json` | REST purest. | Complex client implementation. |

**Expert Recommendation:** Use **URI versioning** for major architectural shifts (e.g., moving from XML to JSON). Use **Header-based versioning** for iterative data model changes.

3. The "Expand and Contract" Pattern

To safely remove or rename a field, follow this three-phase rollout:

1. **Phase 1 (Expand):** Add the new field (`new_email`) to the response but keep the old field (`email`). Both fields return the same data.

2. **Phase 2 (Migrate):** Update documentation and issue **Deprecation Headers** (e.g., `Sunset: Wed, 15 May 2025`). Encourage clients to switch.

3. **Phase 3 (Contract):** Once telemetry shows 0% usage of the old field, remove it.

4. Schema Evolution: Protobuf and JSON

* **Protobuf:** Uses **Tag Numbers** for field identification. You can rename a field in the `.proto` file as long as the tag number remains the same; the binary format is unaffected. **Rule:** Never reuse a tag number from a deleted field.

* **JSON Schema:** Use "Open Content" models. Ensure your clients are programmed to ignore unknown fields rather than throwing an error (Standard in most JSON parsers like Jackson/Gson).

5. Automated Verification

* **Consumer-Driven Contracts (CDC):** Use tools like **Pact**. Consumers provide a "contract" of what they expect. The provider runs these tests before every deployment. If a change breaks a consumer's contract, the build fails.

---

**See Also:**

- [Api Design Best Practices](ApiDesignBestPractices) — Building stable contracts.

- [Canary Deployments](CanaryDeployments) — Testing changes in isolation.

- [Developer Experience](DeveloperExperience) — Communicating changes effectively.