Skip to content

13. Honest Admission — good API menus still leave unsolved arguments behind

~13 min read. Senior API designers sound calm because they know what remains messy.

Built on the ELI5 in 00-eli5.md. The menu — API documentation — looks neat, but the kitchen decisions behind it still contain trade-offs without perfect answers.


1) REST versus RPC is still an unsettled working argument

People love declaring one winner. "REST is pure." "RPC is practical." Both lines hide context.

REST gives strong resource language, cache-friendly semantics, and familiar HTTP patterns. RPC gives explicit actions, tighter operation naming, and often easier mental mapping for workflows.

A payments API might expose /payments/{id}/refunds cleanly. An internal service might simply say RefundPayment. Both can be sensible.

REST lens ──→ resource first
RPC lens  ──→ action first

The real question is not ideology. It is fit. Who are the clients? How many actions feel unnatural as resources? How much tooling depends on HTTP semantics?

Worked example. A public commerce platform usually benefits from REST-like predictability. Developers expect nouns, status codes, and pagination patterns. An internal machine-learning scoring service may prefer RPC calls where operations are task-like and strict.

So the honest answer in interviews is mature. Choose a style that matches domain shape, consumer expectations, and platform tooling. Do not pretend one style erased trade-offs forever.

2) API governance at scale remains more process than theorem

Small teams keep consistency by proximity. One hallway talk fixes naming. One reviewer catches weird fields. Large organizations do not work that way.

When fifty teams ship APIs, consistency becomes a governance problem. Who approves patterns? Who owns naming conventions? Who decides pagination style, error shape, and authentication rules?

A central platform team helps. So do style guides, linters, shared middleware, and reusable schemas. Still, none of these remove coordination cost.

many teams ──→ many APIs ──→ drift risk
          └─→ governance helps,
              but never finishes completely

Worked example. Suppose three teams expose customerId, customer_id, and clientId for the same concept. All are understandable. Together they create SDK pain, documentation confusion, and duplicated mapping logic.

Now add independent release calendars. The governance team may publish rules, but adoption lags. Some services stay legacy. Some exceptions are justified. Some exceptions are merely political.

So governance is unsolved in the strict sense. You can improve it greatly. You cannot reduce it to one universal checklist. The menu stays partly social, not only technical.

3) Backward compatibility is art,

not pure science

Everyone says, "Do not break clients." Good advice. Hard reality. What counts as breaking depends on client behavior, not just your diff.

Removing a field is obviously risky. Changing nullability is risky. Changing enum values is risky. But even adding fields can break fragile clients that assumed a closed schema.

See the awkward truth.

server thinks: additive change
client reality: parser crashes anyway

Worked example. A response currently returns:

{ "status": "active" }

Later you add:

{ "status": "active", "warnings": [] }

Standards-minded engineers may say, "Additive, so safe." A brittle mobile parser may still fail. That means compatibility is empirical, not philosophical.

Another example. Changing sort order may not alter schema. Still, a client using "first item means newest" quietly breaks. Behavioral contracts matter too.

That is why strong API teams use empathy, telemetry, beta rollouts, and consumer conversations. Not every compatibility risk is visible from the OpenAPI file alone.

4) Versioning has no perfect solution

URI versioning is clear. Header versioning is cleaner to some teams. Date-based versioning fits fast-moving platforms. No versioning with additive discipline sounds elegant. Every option creates new pain somewhere.

/v1/orders          ── clear but noisy
Accept-Version: 1   ── cleaner path,
                      harder tooling sometimes
date versions       ── product-friendly,
                      lifecycle-heavy

Worked example. Path versioning helps docs and caching. But v1, v2, and v3 can create permanent duplicate maintenance. Header versioning avoids path clutter, but debugging via curl becomes less obvious. Date versions communicate support windows, but can overwhelm customers with policy tracking.

Some teams avoid explicit versions and rely on strict backward compatibility. That sounds ideal until a truly incompatible change arrives. Then everyone rediscovers versioning under stress.

So the mature line is simple. Versioning is a trade-off between clarity, operational cost, and change frequency. There is no perfect versioning pattern, only a least-bad fit for your ecosystem.

5) OpenAPI specs drift unless teams design for alignment continuously

Specification drift is extremely common. Docs say one thing. Implementation does another. SDKs quietly assume a third shape. That triangle hurts everyone.

Drift happens for boring reasons. Fast fixes skip spec updates. Generated code is edited manually. Examples lag behind handlers. Error responses never get documented properly.

spec ──→ generated client
  ├── implementation changes faster
trust drops

Worked example. The spec says status enum is pending|done. Backend later adds failed during an urgent launch. Web dashboard handles it. External SDKs do not. Nobody noticed because only success flows were tested.

Another example. The spec says one field is required. Implementation started defaulting it silently. Now new consumers depend on the silent default. Later the platform team removes that default. A hidden contract was created outside the spec.

Good teams reduce drift with automation. Generate examples from tests. Fail CI when handlers and spec disagree. Review docs as part of API changes. Still, perfect alignment at scale stays hard.

That is the final honest admission. The menu is necessary. The menu is never the whole truth by itself. Healthy API programs keep reconciling docs, behavior, and consumer reality.


Where this lives in the wild

  • Google API governance lead balances REST guidance, internal RPC realities, and the politics of many product teams.
  • Stripe developer experience engineer protects compatibility carefully, knowing even additive changes can surprise old integrations.
  • Amazon platform architect chooses versioning strategies across services with different client lifecycles and operational constraints.
  • Salesforce API program manager fights spec drift where docs, SDKs, and implementations evolve on different schedules.
  • Postman platform engineer builds governance, linting, and collaboration workflows because consistency never holds automatically.

Pause and recall

  1. Why is the REST versus RPC debate still unsettled?
  2. What makes API governance partly social, not only technical?
  3. Why can even additive changes break clients sometimes?
  4. What causes OpenAPI spec drift in practice?

Interview Q&A

Q: Why not declare REST always better than RPC? A: Different domains, clients, and tooling needs make each style fit some problems better. Common wrong answer to avoid: "Because REST is only for public APIs" — internal and external boundaries can use either style thoughtfully.

Q: Why is backward compatibility called art instead of science? A: Real client behavior, undocumented assumptions, and rollout timing affect safety beyond schema diffs. Common wrong answer to avoid: "Because developers are careless" — care helps, but compatibility risk is genuinely hard to observe fully.

Q: Why is there no perfect versioning strategy? A: Every versioning approach shifts pain between clarity, maintenance cost, and client complexity. Common wrong answer to avoid: "Because teams have not standardized enough" — standards help, but trade-offs remain even with discipline.

Q: Why does spec drift persist even with OpenAPI? A: Specs help, but implementation speed, manual exceptions, and weak enforcement create divergence over time. Common wrong answer to avoid: "Because OpenAPI is flawed" — the deeper issue is process and alignment, not only the format.


Apply now (5 min)

Exercise: Pick one API you know. Write one unresolved choice about style, one compatibility risk, one versioning concern, and one spec-drift prevention step. Keep each point to one sentence.

Sketch from memory: Draw one menu, one implementation, and one SDK. Mark the three places where drift or debate can appear first.


Bridge. The API boundary is done. Next we move behind it into storage, where data models, indexing, and caching rules begin. → ../05_databases_storage_caching/00-eli5.md