LPI Web Dev Essentials study materials
LPI Web Dev Essentials study resources

Order API Default Format Change Under Legacy Client Load

LPI Web Dev Essentials · Put your knowledge to work in context.

All case studies

Order API Default Format Change Under Legacy Client Load

Northwind Logistics runs a public order-tracking API used by 1,400 active mobile installs. The v1 endpoint returns XML by default, paginates with page/per_page, and exposes the internal warehouse code as wh. A new partner integration needs JSON, cursor pagination, and must not see warehouse codes. A developer proposes changing /v1/orders to return JSON by default and renaming wh to warehouse_id, arguing that clients "should have sent Accept headers." The mobile app's release cycle is 6-8 weeks, and 9% of installs are on versions older than 18 months. The product manager wants the partner live in three weeks. Traffic logs show 72% of v1 requests come from the old app, 21% from a spreadsheet plugin that ignores response headers, and 7% from internal scripts. The team has no API gateway, only an Express service behind nginx, and no automated contract tests.

1. Assess whether changing the default response format of `/v1/orders` is safe. What evidence would you gather before deciding, and what failure modes should the team expect?

Read the worked answer

Changing a default is a breaking change even if the endpoint path is unchanged: clients that never sent Accept relied on XML, and the spreadsheet plugin ignores response headers entirely, so content negotiation cannot save it. The 72% mobile share is the largest exposure, but the 21% plugin share is the least controllable because there is no release process. Evidence should include per-client User-Agent/API-key breakdown of requests, sampled response parsing errors, and a canary of the new behavior behind a key or header. Failure modes: XML parsers receiving JSON and failing at the first character; clients that silently coerce JSON into an empty XML document; caching layers storing one representation and serving it to another client; internal scripts scraping the old wh field. Absent contract tests, the team cannot prove compatibility. The safer judgement is to add a new representation rather than mutate the default, and to treat the plugin as a hard compatibility constraint until its owner is identified.

2. Design a versioning and deprecation plan that meets the partner's three-week deadline without an API gateway. Include concrete HTTP signals and a rollout order.

Read the worked answer

Introduce a new major version, /v2/orders, with JSON-only responses, cursor pagination, and a curated field set excluding wh. Keep /v1/orders returning XML by default; optionally allow JSON on v1 only via explicit Accept: application/json, but do not make it the default. Rollout order: (1) add contract tests from recorded v1 requests and responses; (2) ship v2 behind an API key allowlist for the partner; (3) validate cursor stability and pagination edge cases; (4) publish deprecation metadata on v1 using Deprecation and Sunset headers plus a Link header to documentation; (5) add Warning: 299 only if the team can tolerate non-standard clients; (6) set a sunset date beyond the mobile app's 18-month tail, not three weeks. Use nginx map rules or Express middleware to route /v2 to a separate router, so version isolation does not require a gateway. Return 410 Gone after sunset rather than silently changing v1. The partner's three-week deadline is met by v2, not by forcing v1 clients to change.

3. The partner must not see warehouse codes, but internal scripts currently depend on `wh`. How would you satisfy both without exposing the field to external consumers?

Read the worked answer

Split the representation by audience rather than by endpoint alone. In v2, omit wh from the default serializer and expose only a stable public location identifier. Internal scripts should move to an internal endpoint or a privileged scope, such as an API key claim that permits warehouse:read, with the field included only when that claim is present. Do not rely on obscurity: a field present in JSON is visible to the partner even if undocumented. If internal scripts cannot be changed immediately, run them against a private v1-compatible route on an internal hostname or mTLS-protected listener, and log their usage so they can be migrated. Validate with a response-schema test that asserts wh is absent for partner keys and present for internal keys. This preserves the compatibility constraint while making the security boundary explicit in code and tests.