Lesson 13 of 30
An API a frontend depends on will change. The question isn't whether to hope that never happens — it's what concrete code patterns make a client resilient when it does.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
A frontend team keeps calling a `/v1/orders` endpoint because 'it still works fine.' What real risk does this create?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
An API a frontend client depends on will change over time — fields get added, fields get deprecated, whole response shapes evolve. A frontend client needs real, concrete patterns for surviving that, rather than assuming the shape it was built against is permanent. Three patterns matter in practice:
/v2/orders existing alongside /v1/orders) is a real, common pattern during a migration window, and a frontend team has to know how to navigate it — including the operational reality that a deprecated version eventually gets removed, and migrating off it has to actually happen before that date, not sit indefinitely.type OrderResponse = {
id: string;
total: number;
// Added in a later API rollout — not guaranteed present yet on every request
discountCode?: string;
};
function renderOrderSummary(order: OrderResponse) {
const discountLine =
"discountCode" in order && order.discountCode
? `Discount applied: ${order.discountCode}`
: null;
return { total: order.total, discountLine };
}
The "discountCode" in order check is the feature-detection: this code works correctly whether it's talking to a backend that has shipped the field yet or not, instead of crashing (or silently rendering undefined) on whichever side hasn't caught up.
// Defensive parsing: pull out only what's needed, don't assume the rest
function getOrderTotal(raw: unknown): number {
if (
typeof raw === "object" &&
raw !== null &&
"total" in raw &&
typeof (raw as { total: unknown }).total === "number"
) {
return (raw as { total: number }).total;
}
throw new Error("Unexpected order shape: missing numeric total");
}
order.discountCode?.toUpperCase() handles a missing value gracefully at the point of use, but it doesn't tell you why it's missing — genuinely absent this order, or not yet rolled out on the backend the client is talking to — which matters when deciding whether to show a fallback UI or just omit the feature entirely./v1/ as safe to keep calling indefinitely because it "still works" is how a team gets caught by a real breaking removal on a schedule they weren't tracking."An API you depend on adds a new field or bumps its version — how does your client handle that without breaking?" is a real, practical question, and naming defensive parsing, feature detection, and a real migration plan off a deprecated version — not just "we'd update the code eventually" — shows you've actually maintained a client against a changing API.