Overview

15 Modifying an API

APIs rarely remain static, so modifying them demands the same care as designing them from scratch: continue to meet needs while staying user-friendly, interoperable, secure, efficient, and aligned with context. The chapter shows how seemingly simple changes—like replacing a single-value field with a collection or restructuring a price into value-plus-currency—can break consumers if deployed abruptly. It emphasizes planning and communication, favoring backward-compatible adjustments when possible, and, when not, managing change through clear versioning and transition paths. A robust initial design significantly reduces the risk and cost of future changes.

The chapter maps where breaking changes arise and how to avoid them: output and input data (only add or widen limits to remain compatible), resource paths and operations (renames, removals, and method swaps break), HTTP status codes (strict checks and behavior shifts can fail clients), and multi-step flows (inserting new steps can silently break use cases). It calls out the “invisible contract” where consumers rely on undocumented behaviors, and advises preventing unintended changes via OpenAPI-aware diffs, CI/CD checks, and thorough testing. Security changes require special care: replacing schemes (for example, API key to mutual TLS) is necessarily breaking; scope changes can break or introduce breaches if misaligned. Versioning is framed as an interface concern distinct from implementation; semantic versions are preferred (with date-based as an alternative), path-level version signaling is the default, and choosing scheme and representation early avoids confusion. Sub-API-level versioning (per resource or operation) is discouraged for complexity and interoperability reasons.

To limit future breakage, the chapter promotes extensible design: provide ready-to-use, interpretable data; accept extra input gracefully; design flexible flows; and keep APIs right-sized rather than monolithic. It recommends learning from past trade-offs and adopting patterns that evolve well: always wrap bodies in objects, prefer arrays of objects over atomics, use interpretable standards (such as ISO durations), group similar data in arrays, favor enumerations over booleans, and expose operations instead of hard-coded enumerations that change frequently. When breaking is justified, evaluate impacts by identifying consumer types and usage, determine if multiple versions can run concurrently (e.g., adapters), align with versioning policy, and balance cost against consumer and business value. Communicate changes with OpenAPI: set the API version, mark deprecated elements, maintain a changelog, and, at runtime, surface deprecation with a Sunset header to guide smooth migrations.

Modifying a consumed API is "design as usual" with the constraint of determining how modifications will affect consumers and making trade-offs, if necessary. The initial design can facilitate later modifications.
CH15 F01 lauret3
Caring for design modification starts when creating an API. Modifying an API is "design as usual" with the addition of caring for breaking changes and modification logs.
CH15 F02 lauret3
Breaking changes can occur in headers and bodies of any success or error response. Only add data or modify it within the limits of the original one to be backward-compatible.
CH15 F03 lauret3
The breaking changes in output data require updating the consuming applications' code. Backward-compatible changes have no impact on non-updated consumers, but they won’t use the newly added data.
CH15 F04 lauret3
Breaking changes are introduced while enhancing an error data model. The error list is renamed, and specific error types are replaced by generic ones.
CH15 F05 lauret3
Breaking changes can occur in request bodies, headers, query parameters, and path (including path parameters). Only make required data optional, add new optional data, and expand the limits of existing data to be backward-compatible.
CH15 F06 lauret3
The breaking changes in the data model require updating the consumer code. Backward-compatible changes have no impact on consumers. However, non-updated applications will continue to send removed data and never send newly added data.
CH15 F07 lauret3
We version the API from the consumer perspective. Implementation modifications that don’t affect the interface contract are not reflected in the API version numbering.
CH15 F08 lauret3
Semantic versioning indicates the type of change, while date-based versioning doesn’t.
CH15 F09 lauret3
The API version can be indicated in the path, domain name, query parameter, header, media type, or an out-of-the-band configuration.
CH15 F10 lauret3
We can indicate the API version or API plus document version in info.version.
CH15 F11 lauret3
Use the deprecated flag to mark elements that should no longer be used but must be kept to maintain backward compatibility.
CH15 F12 lauret3
Leverage Markdown to add changelogs to the API and any element that supports description. Consider adding tags to highlight modified operations.
CH15 F13 lauret3

FAQ

What counts as a breaking change versus a backward-compatible change?Breaking changes force consumers to update their code to keep working; backward-compatible changes do not. Rules of thumb: - Breaking: removing or renaming fields/operations/paths; changing types, formats, or meaning; shrinking ranges/enums; altering flows or required security; changing HTTP methods; replacing expected status codes with different classes. - Backward-compatible: adding new optional inputs; expanding ranges/enums for inputs; adding new fields to responses; always returning previously-optional response fields; adding new operations; stopping the use of a specific error/status (without changing behavior).
Which response (output) data modifications are safe, and which will break consumers?Safe (backward-compatible): - Add new response properties (consumers can ignore). - Start always returning previously-optional properties. - Shorten string limits (usually safe for outputs). Risky/breaking: - Remove or rename properties; change nesting. - Change type/format (e.g., number → string, timestamp → ISO8601). - Shrink enums or tighten numeric/string limits. - Add enum values that clients interpret strictly. - Remove expected headers (e.g., Location).
Which request (input) data modifications are safe, and which will break consumers?Safe (backward-compatible): - Make required inputs optional. - Add new optional inputs or headers. - Expand ranges and enums. - Add optional objects that contain their own required fields (only validated when present). Breaking: - Remove supported values (e.g., enum); tighten limits. - Rename fields or restructure the payload. - Change types/formats (e.g., string → date-time). - Change semantics (e.g., cents → dollars) without versioning. - Introduce new required headers/params (e.g., If-Match) without a migration path.
How should I version: the API or the implementation?Version the interface contract (what consumers see), not the implementation. Implementation-only changes (refactors, performance, bug fixes that don’t alter the interface) should not change the API version. Keep separate version streams and communicate API versions clearly.
Which versioning scheme and representation should I use?Recommendations: - Scheme: Prefer semantic versioning (MAJOR.MINOR). MAJOR for breaking changes; MINOR for backward-compatible updates. Date-based versions can work for frequent, regular releases. - Representation: Prefer path-level major versioning (e.g., /v2/accounts). Alternatives: custom header (Version), custom media type (e.g., application/vnd.myapi.v2+json), or domain (api-v2.example.com). Avoid query parameters for versioning.
How do I manage unavoidable breaking changes and consumer impact?Steps: - Assess impact: who/how many consumers, and do they use what will break (scopes, logs, code analysis)? - See if multiple versions can run concurrently (single instance with request/response adapters or multiple instances). - Follow the versioning policy (supported versions, deprecation windows). - Provide a migration path (parallel versions, redirects when feasible, thorough changelogs). - Signal deprecation at runtime (Sunset response header) and in docs; coordinate timelines.
How can I prevent accidental breaking changes before deploying?Use OpenAPI-aware diff tools in CI/CD to compare old/new specs and flag breaking changes. Also: - Treat the OpenAPI doc as source of truth and test implementation against it. - Test for behavior changes not in the spec (e.g., status codes, headers, rate-limit errors). - Watch for “invisible contracts” (undocumented behaviors consumers depend on, like array ordering or gateway-injected 429 errors).
What security-related modifications are risky?Breaking: - Replacing/removing security schemes (e.g., API key → mTLS). Mitigate by supporting both during migration. - Reassigning operations to different scopes (clients must request new scopes). Mitigate by temporarily allowing overlap. Security breaches risk: - Overly broad scopes or adding powerful operations to user-level scopes. Revisit scope design to follow least privilege.
Which design patterns make an API more extensible (and less likely to break)?Adopt: - Use objects at top-level bodies (not arrays/atomics) to add fields later. - Prefer arrays of objects over arrays of primitives if elements may evolve. - Use interpretable/extensible formats (e.g., ISO8601 date/duration). - Group similar items in arrays (events/statuses) to add entries without changing shape. - Prefer enums over booleans; when enums change often, expose a lookup operation instead of hardcoding values. - Design flexible flows, accept extra input data, and split do-it-all APIs into right-sized ones.
How should I document modifications with OpenAPI?Do the following: - Set info.version to the API version (e.g., 1.2); optionally use PATCH digit for document-only updates (1.2.1). - Update servers (base URL) or operation-level headers/media types if the version is expressed there. - Mark deprecated operations/params/headers/properties with deprecated: true. - Add a changelog in info.description and, when helpful, at operation/schema level; tag modified/new operations (e.g., “Modified by v1.2”). - Use OpenAPI diffs to generate change lists; add notes for non-spec-visible changes (status behavior, invisible contracts).

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • The Design of Web APIs, Second Edition ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • The Design of Web APIs, Second Edition ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • The Design of Web APIs, Second Edition ebook for free