Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Backward-Compatible API Evolution
HLD

Backward-Compatible API Evolution

Changing APIs without breaking consumers — additive changes, the safe-change checklist, and deprecation mechanics.

The Core Rule

 an API change is BACKWARD COMPATIBLE if existing clients
 keep working unchanged after the server ships it
 
 old client + new server = works        ← the invariant to protect
 new client + old server = your choice (forward compat, later lesson)

You can’t force-deploy clients; mobile apps lag months, third parties lag years. Server-side changes must therefore assume the oldest supported client is still out there.

What’s Safe to Change

ChangeSafe?Notes
Add optional response fieldClients ignoring unknown fields stay fine
Add optional request paramOld clients just don’t send it
Add new endpointPure addition
Add new enum valueBreaks exhaustive-switch clients!
Remove fieldDeserialization errors / data loss
Rename fieldSame as remove + add
Make optional → requiredOld requests now fail
Change field type/semanticsSilent corruption worst case
Tighten validationPreviously-valid calls start failing

The enum trap deserves emphasis: adding status=refunded breaks any client with a closed switch statement. Either version the resource or require tolerant readers.

The Tolerant Reader Pattern

 CLIENT side discipline that makes evolution possible:

 - ignore unknown fields (never fail on extra JSON keys)
 - treat unknown enum values as "unrecognized" not error
 - never assume response contains exactly what docs promised

 servers evolve freely ⇔ clients read tolerantly.
 enforce via codegen defaults and lint rules, not hope

Deprecation Mechanics

When removal is truly needed:

 1. announce     changelog + direct notice to active consumers
 2. mark         docs say deprecated; responses add Sunset header
                 Deprecation: true
 3. observe      log which clients still call the dead path
 4. migrate      contact holdouts; offer migration window
 5. remove       only when observed traffic ≈ zero

 typical runway: 6–12 months for public APIs,
 one release cycle for internal ones

Versioning Strategies (preview)

 URL path      /v2/trips        explicit, cacheable, most common
 header        Accept: vnd.api+json;version=2   cleaner URLs, hidden
 query param   ?version=2       simple but pollutes caching keys

 full versioning is a LAST resort — most changes should fit
 inside additive-compatible evolution. version when you must
 make a BREAKING change, and run v1/v2 side by side during
 migration, then retire v1 on the same deprecation schedule

Interview Framing

“How do you evolve this API?” tests operational empathy. Scored shape: state the invariant (old client × new server), classify candidate changes against the safe table, name the enum/tolerant-reader subtlety unprompted, sketch deprecation-with-observability rather than big-bang removal. That sequence signals someone who has shipped breaking changes before — or wisely avoided it.

My Private Notes

Notes are auto-saved locally to this device.