14 Adapting API design to context
Great API designs are context-aware: beyond security and efficiency, they must account for consumer capabilities, domain standards, communication patterns, the nature of data and operations, implementation realities, and business or infrastructure constraints. The chapter shows how to surface these factors early, challenge assumptions, and then make pragmatic trade-offs when needed. Typical adaptations include supporting method-limited clients via the X-HTTP-Method-Override header; offering content negotiation or separate APIs to reconcile XML/JSON audiences; handling planned downtime with 503 plus Retry-After or by accepting requests and returning 202 Accepted; ensuring URL-safe identifiers and controlling URL length; and preferring JSON Merge Patch for partial updates while accommodating alternatives when warranted.
Files demand tailored flows, models, and documentation. The text contrasts attaching documents directly to business resources with using a generic File API, and explains one-shot submissions that mix data and binaries via Base64 (larger payloads) or multipart/form-data (more efficient, but not universally supported). It details how to describe raw and mixed bodies in OpenAPI (content types, encodings, multipart parts) and how to keep file exchange efficient: don’t echo files on upload, enable caching and conditional requests, support partial transfer with Range and Content-Range, and use Expect: 100-continue to avoid waste. When infrastructure can’t transit binaries, delegate to storage systems with signed URLs—redirect downloads with 303 See Other and provide upload instructions (URL, method, headers) instead of proxying content.
For provider-originated events and long-running work, the chapter recommends webhooks and callbacks. Webhooks should be optional and interoperable (e.g., CloudEvents), include the right payload granularity (lightweight pointers for volatile or large data, heavier payloads for small/static data), be secured (signatures, mutual TLS, allowlists, OAuth), respond quickly with a 2xx, and offer failure strategies (automatic retries, on-demand redelivery, history) with clear OpenAPI descriptions. Long operations should return 202 with a status resource, progress and timing hints, or use callbacks to avoid polling; the Prefer header can allow selective synchronous handling. Finally, designers should stay tool-agnostic and consider alternatives to REST—event-driven architecture for internal events, Server-Sent Events for streams, WebSockets for bidirectional chat, GraphQL for backend-for-frontend needs, and gRPC for efficient service-to-service—choosing the best fit for the context.
Many contextual factors other than security and efficiency constrain API design.
The Verify Account Information operation request with custom JSON and standard ISO20022 data.
We can send a mix of data and files by encoding file content in Base64 strings in JSON or using the multipart/form-data media type.
Base64 encodes any binary or textual data into a string; it can be embedded into a JSON string.
When we can’t directly return file content to the consumer, we can leverage a 303 See Other redirection response to redirect consumers to the file.
When we can’t directly receive file content, we can provide an operation that generates a URL targeting a system that can receive it in the place of our API.
The Banking notification system calls the Transaction Notification webhook to prevent the consumers from polling transactions.
The Banking notification system notifies a consumer of a new transaction with a POST request whose body leverages the CloudEvents format.
A light event only contains a reference that can be used to get data via a regular API call. A heavy event contains usable data and may not necessitate an API call.
Webhooks go under the webhooks property of the OpenAPI document. A webhook doesn’t have a path but an identifier. For the rest, a webhook is defined like any other operation under paths.
An operation callback is defined under callbacks within the operation object. Its path can be static or contain runtime variables. We use a design consistent with the previously defined transaction notification webhook.
The Design of Web APIs, Second Edition ebook for free