API Bites — Request and Response Protocols

Methods, Headers, Status Codes and Response Caching

TRGoodwill
API Central
7 min readNov 11, 2022

--

API Development Standards are a focused collection of imperatives, conventions and guidance, and are intended to improve the consistency, stability, generality, predictability and usability of business resource APIs.

The following ‘sample’ guidance is focused on request and response protocols, and is an excursion from the parent article, Writing API Development Standards.

HTTPS

Expose only HTTPS TLS-encrypted endpoints to API resources and operations. Ideally, restrict to TLS versions ’n’ or ‘n-1’ (e.g. ‘TLS 1.3 or 1.2’), and do not redirect HTTP to HTTPS. Consider locking down APIs with mutual authentication between the API Gateway and resource servers — this should be mandatory for sensitive data. More on transport security here.

HTTP Request Methods

RESTful API operations are based on the standard HTTP Request Method definitions. When interaction is synchronous and when a process or transformation is the natural responsibility of an entity or value object, transparent HTTP verbs and HTTP response codes should apply to the business resource instance, unless significant complexity dictates otherwise.

Per Mozilla.org — “An HTTP method is safe if it doesn’t alter the state of the server. In other words, a method is safe if it leads to a read-only operation.” Per Restfulapi.net — “In the context of REST APIs, when making multiple identical requests has the same effect as making a single request — then that REST API is called idempotent.” Idempotent APIs improve fault tolerance.

The below table describes the standard HTTP verbs that might be supported by a resource server.

The relatively new HTTP QUERY method is the safe, idempotent, cache-able way of encapsulating queries against a resource collection — however the QUERY method remains unsupported by OpenAPI 3 and many API management platforms at the time of writing. More on queries & filtering here.

A PUT method requests replacement of the entire resource, while a PATCH method requests that a set of changes be applied to the resource (which may potentially be just one or two fields). PATCH payload will typically be smaller and require less input and data marshalling on the client end — PATCH should be used in preference to PUT for partial updates. A PATCH method should be implemented in an idempotent manner — that is to say; multiple identical requests should have the same effect as making a single request.

DELETE method support is not always appropriate for a business resource —both historical and proto-engagement data has enduring and evolving value within an organization. Resource lifecycle transitions that result in an inactive status will often be managed by the resource service, and decoupled from subsequent policy-driven data management activities.

Enterprise-wide support for the HEAD method provides an avenue for a standardized, safe and consistently implemented service health check mechanism.

HTTP Request Headers

HTTP header information will be used for processing, traceability, logging and auditing purposes. The list below describes headers for API requests that API resource servers should understand and deal with appropriately.

  • Authorization : OAuth 2.0 access token, in the format: Bearer [token]
  • api-key : The API Key (~client_id) registered with the developer portal. This key identifies the client application for accounting and metric purposes. Ideally, cross-matched against the client_id provided in the enterprise access token for stronger identity assurance.
  • Content-Type : API requests containing an entity-body must include a Content-Type header, expressed as an OpenAPI 3 supported MIME type, corresponding to the entity-body format, e.g.
    application/json (JSON data)
    application/xml (xml data)
    multipart/form-data (multipart mime)
    application/x-www-form-urlencoded (form data)
  • Accept : API requests expecting an entity-body in the response should include an Accept header to indicate the response media type that should be returned. If this header is not provided, a value of application/json is to be assumed.
  • Request-Id : It is useful to define a header with which a client may pass an identifier (such as a UUID) uniquely identifying the API call end-to-end, e.g. c5ff1e53-1c48-4be6-9b53-c966886e539f. Consider whether this header should be mandatory — this identifier may be generated in the API Gateway when not provided by the client.
  • x-jws-signature : Optional payload signing to support data Integrity and Non-Repudiation. More here.
  • Connection : Control options for the current connection. For example keep-alive
  • Date : The date and time that the message was created, For example Tue, 11 Oct 2022 09:27:30 GMT
  • Cache-Control : Used to specify directives that must be obeyed by all caching mechanisms e.g. no-cache
  • If-None-Match and If-Match: A string of ASCII characters placed between double quotes. Matches the content of the server-provided ‘Etag’ header. The client may include this in any update requests to ascertain whether the version of a resource is unchanged. E.g. "34a64df551425fdc55e4d42a146795d9f25f89d2"
  • traceparent and tracestate : W3C Trace Context headers. More here.

HTTP Response Headers

  • Content-Type : API responses containing an entity-body must include a Content-Type header to declare the content type, expressed as a MIME type.
  • Request-Id : The unique identifier (e.g. UUID) provided by the API client in the API request, e.g. c5ff1e53-1c48-4be6-9b53-c966886e539f
  • Location : API responses to a POST operation that has successfully created a new resource should return a ‘201 Created’ status code, and a ‘Location’ header containing the relative path of the newly created resource. e.g. v1/customers/12B34C
  • ETag : A string of ASCII characters placed between double quotes. Used to identify the particular version of a resource. Enterprise guidance on ETag headers is recommended. Consistent implementation is strongly supportive of caching, concurrency control, EDA and reconciliation. e.g. "34a64df551425fdc55e4d42a146795d9f25f89d2"
  • x-jws-signature : Optional payload signing to support data Integrity and Non-Repudiation. More here.
  • traceparent and tracestate : W3C Trace Context headers. More here.
  • Cache-Control : Used to specify directives that must be obeyed by all caching mechanisms, measured in second, For example no-cache or max-age=3600
  • Date : The date and time that the response message was created, e.g. Tue, 11 Oct 2022 09:27:30 GMT
  • Expires : Gives the date/time after which the response is considered stale e.g. Tue, 11 Oct 2022 09:27:30 GMT
  • Link : WebSub link headers required to support dynamic subscription to a WebSub hub. Created as 2 logical HTTP ‘Link’ headers of relationship type “self” (topic) and “hub” (subscription endpoint) which equates to a single comma-delimited Link header: e.g.
    <v1/customers/12B34C; rel="self", <v1/events/subscribe; rel="hub">

HTTP Response Status Codes

Not all HTTP status codes will apply to every operation. The table below indicates the HTTP Response codes that may be appropriate for a resource server to return against each of the commonly supported HTTP methods.

Response Caching

Not all APIs require, or should support caching. It is important to understand how HTTP caching can impact APIs. There are two HTTP cache headers: Cache-Control and Expires.

Cache-Control

Cache-Control notifies if the client agent should cache. It supports three main values:

  • public : caching can occur anywhere within the network traffic such as intermediate proxies.
  • private : caching can occur anywhere within the network traffic such as intermediate proxies.
  • no-cache : no caching should be done — though this is not always the case due to the complexity of the network.

Optionally accompanying the Cache-Control directive is the max-age value. The max-age value is defined in seconds and how long the response can be cached before it is considered stale. e.g. Cache-Control: public, max-age=3600 meaning that any part of the network can cache the content for one hour.

Expires

The Expires directive when used alongside Cache-Control sets a date when the content is considered stale. If both Expires and max-age is specified max-age will take precedence. e.g.

Cache-Control: public
Expires: Mon, 25 Jun 2019 21:31:12 GMT

Caching in the API Gateway

API Gateways will normally offer a managed response cache service. The API Gateway will thus provide a local copy of the cache, usually registering a cache event listener that replicates messages to the other caches across connected API Gateways so that put, remove, expiry and delete events on a single cache are consistently replicated across all other caches.

Wrap-up

Governed, opiniated standards and patterns will be required to enable seamless interoperability between independent, decoupled domains. While sample guidance is offered in this article, there is often more than one tried-and-tested approach in any one area of API design — specific tactics and conventions should be tailored to the target environment.

--

--

TRGoodwill
API Central

Tim has several years experience in the delivery and evolution of interoperability frameworks and platforms, and currently works out of Berlin for Accenture ASG