Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve guidance for caching support (#451) #482

Merged
merged 4 commits into from
Jan 24, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 96 additions & 95 deletions chapters/common-headers.adoc
Original file line number Diff line number Diff line change
@@ -1,69 +1,60 @@
[[common-headers]]
= Common Headers

This section describes a handful of headers, which we found raised the
most questions in our daily usage, or which are useful in particular
circumstances but not widely known.
This section describes a handful of headers, which we found raised the most
questions in our daily usage, or which are useful in particular circumstances
but not widely known.

[#178]
== {MUST} Use Content Headers Correctly

Content or entity headers are headers with a `Content-` prefix. They
describe the content of the body of the message and they can be used in
both, HTTP requests and responses. Commonly used content headers include
but are not limited to:

* https://tools.ietf.org/html/rfc6266[`Content-Disposition`] can
indicate that the representation is supposed to be saved as a file, and
the proposed file name.
* https://tools.ietf.org/html/rfc7231#section-3.1.2.2[`Content-Encoding`]
indicates compression or encryption algorithms applied to the content.
* https://tools.ietf.org/html/rfc7230#section-3.3.2[`Content-Length`]
indicates the length of the content (in bytes).
* https://tools.ietf.org/html/rfc7231#section-3.1.3.2[`Content-Language`]
indicates that the body is meant for people literate in some human
language(s).
* https://tools.ietf.org/html/rfc7231#section-3.1.4.2[`Content-Location`]
indicates where the body can be found otherwise
(<<179>> for more details]).
* https://tools.ietf.org/html/rfc7233#section-4.2[`Content-Range`] is
used in responses to range requests to indicate which part of the
requested resource representation is delivered with the body.
* https://tools.ietf.org/html/rfc7231#section-3.1.1.5[`Content-Type`]
indicates the media type of the body content.
Content or entity headers are headers with a `Content-` prefix. They describe
the content of the body of the message and they can be used in both, HTTP
requests and responses. Commonly used content headers include but are not
limited to:

* {Content-Disposition} can indicate that the representation is supposed to be
saved as a file, and the proposed file name.
* {Content-Encoding} indicates compression or encryption algorithms applied to
the content.
* {Content-Length} indicates the length of the content (in bytes).
* {Content-Language} indicates that the body is meant for people literate in
some human language(s).
* {Content-Location} indicates where the body can be found otherwise (<<179>>
for more details]).
* {Content-Range} is used in responses to range requests to indicate which part
of the requested resource representation is delivered with the body.
* {Content-Type} indicates the media type of the body content.

[#133]
== {MAY} Use Standardized Headers

Use http://en.wikipedia.org/wiki/List_of_HTTP_header_fields[this list]
and mention its support in your OpenAPI definition.
Use http://en.wikipedia.org/wiki/List_of_HTTP_header_fields[this list] and
mention its support in your OpenAPI definition.

[#179]
== {MAY} Use Content-Location Header

The Content-Location header is _optional_ and can be used in successful
write operations (PUT, POST or PATCH) or read operations (GET, HEAD) to
The {Content-Location} header is _optional_ and can be used in successful write
operations ({PUT}, {POST}, or {PATCH}) or read operations ({GET}, {HEAD}) to
guide caching and signal a receiver the actual location of the resource
transmitted in the response body. This allows clients to identify the
resource and to update their local copy when receiving a response with
this header.

The Content-Location header can be used to support the following use
cases:

* For reading operations GET and HEAD, a different location than the
requested URI can be used to indicate that the returned resource is
subject to content negotiations, and that the value provides a more
specific identifier of the resource.
* For writing operations PUT and PATCH, an identical location to the
requested URI can be used to explicitly indicate that the returned
resource is the current representation of the newly created or updated
resource.
* For writing operations POST and DELETE, a content location can be used
to indicate that the body contains a status report resource in response
to the requested action, which is available at provided location.

*Note*: When using the Content-Location header, the Content-Type header
transmitted in the response body. This allows clients to identify the resource
and to update their local copy when receiving a response with this header.

The Content-Location header can be used to support the following use cases:

* For reading operations {GET} and {HEAD}, a different location than the
requested URI can be used to indicate that the returned resource is subject
to content negotiations, and that the value provides a more specific
identifier of the resource.
* For writing operations {PUT} and {PATCH}, an identical location to the
requested URI can be used to explicitly indicate that the returned resource
is the current representation of the newly created or updated resource.
* For writing operations {POST} and {DELETE}, a content location can be used to
indicate that the body contains a status report resource in response to the
requested action, which is available at provided location.

*Note*: When using the {Content-Location} header, the {Content-Type} header
has to be set as well. For example:

[source,http]
Expand All @@ -78,66 +69,73 @@ Content-Location: /products/123/images?format=raw
[#180]
== {SHOULD} Use Location Header instead of Content-Location Header

As the correct usage of Content-Location with respect to semantics and
caching is difficult, we _discourage_ the use of Content-Location. In
most cases it is sufficient to direct clients to the resource location
by using the Location header instead without hitting the
Content-Location specific ambiguities and complexities.
As the correct usage of {Content-Location} with respect to semantics and
caching is difficult, we _discourage_ the use of {Content-Location}. In most
cases it is sufficient to direct clients to the resource location by using
the {Location} header instead without hitting the {Content-Location} specific
ambiguities and complexities.

More details in RFC 7231
https://tools.ietf.org/html/rfc7231#section-7.1.2[7.1.2 Location],
https://tools.ietf.org/html/rfc7231#section-3.1.4.2[3.1.4.2
Content-Location]
More details in RFC 7231 {RFC-7231}#section-7.1.2[7.1.2 Location],
{RFC-7231}#section-3.1.4.2[3.1.4.2 Content-Location]

[#181]
== {MAY} Use the Prefer header to indicate processing preferences
tkrop marked this conversation as resolved.
Show resolved Hide resolved

The `Prefer` header defined in
https://tools.ietf.org/html/rfc7240[RFC7240] allows clients to request
processing behaviors from servers.
https://tools.ietf.org/html/rfc7240[RFC7240] pre-defines a number of
preferences and is extensible, to allow others to be defined. Support
for the Prefer header is entirely optional and at the discretion of API
designers, but as an existing Internet Standard, is recommended over
defining proprietary "X-" headers for processing directives.
The {Prefer} header defined in {RFC-7240}[RFC-7240] allows clients to request
processing behaviors from servers. It pre-defines a number of preferences and
is extensible, to allow others to be defined. Support for the {Prefer} header
is entirely optional and at the discretion of API designers, but as an existing
Internet Standard, is recommended over defining proprietary "X-" headers for
processing directives.

The `Prefer` header can defined like this in an API definition:
The {Prefer} header can defined like this in an API definition:

[source,yaml]
----
components:
headers:
Prefer:
- Prefer:
description: |
The RFC7240 Prefer header indicates that particular server
behaviors are preferred by the client but are not required
for successful completion of the request.
# (indicate the preferences supported by the API)
The RFC7240 Prefer header indicates that a particular server behavior
is preferred by the client but is not required for successful completion
of the request (see [RFC 7240](https://tools.ietf.org/html/rfc7240).
The following behaviors are supported by this API:

# (indicate the preferences supported by the API or API endpoint)
* **respond-async** used to suggest the server to respond as fast as
possible asynchronously using 202 - accepted - instead of waiting for
the result.
* **return=<minimal|representation>** used to suggest the server to
return using 204 without resource (minimal) or using 200 or 201 with
resource (representation) in the response body on success.
* **wait=<delta-seconds>** used to suggest a maximum time the server
has time to process the request.
tkrop marked this conversation as resolved.
Show resolved Hide resolved
* **handling=<strinct|lenient>** used to suggest the server be strict
and report error conditions or lenient and try to continue - if
possible.

type: string
required: false
----

Supporting APIs may return the `Preference-Applied` header also defined
in https://tools.ietf.org/html/rfc7240[RFC7240] to indicate whether the
preference was applied.
Supporting APIs may return the {Preference-Applied} header also defined in
{RFC7240}[RFC-7240] to indicate whether the preference was applied.

[#182]
== {MAY} Consider Using `ETag` Together With `If-Match`/`If-None-Match` Header
tkrop marked this conversation as resolved.
Show resolved Hide resolved

When creating or updating resources it may be necessary to expose conflicts
and to prevent the 'lost update' or 'initially created' problem. Following
https://tools.ietf.org/html/rfc7232[RFC 7232 "HTTP: Conditional Requests"]
this can be best accomplished by using the {ETag} header together {If-Match}
or {If-None-Match} conditional header. The contents of an {ETag}`: <entity-tag>`
header is either (a) a hash of the response body, (b) a hash of the last
modified field of the entity, or (c) a version number or identifier of the
entity version.
{RFC-7232}[RFC 7232 "HTTP: Conditional Requests"] this can be best accomplished
by using the {ETag} header together {If-Match} or {If-None-Match} conditional
header. The contents of an `ETag: <entity-tag>` header is either (a) a hash of the
response body, (b) a hash of the last modified field of the entity, or (c) a
version number or identifier of the entity version.

To expose conflicts between concurrent update operations via {PUT}, {POST},
or {PATCH}, the `If-Match: <entity-tag>` header can be used to force the server
to check whether the version of the updated entity is conforming to the
requested `<entity-tag>`. If no matching entity is found, the operation is
requested {entity-tag}. If no matching entity is found, the operation is
supposed a to respond with status code {412} - precondition failed.

Beside other use cases, `If-None-Match: *` can be used in a similar way to
Expand All @@ -152,36 +150,39 @@ follows in the API definition:
----
components:
headers:
ETag:
- ETag:
description: |
The RFC7232 ETag header field in a response provides the current entity-
tag for the selected resource. An entity-tag is an opaque identifier for
different versions of a resource over time, regardless whether multiple
versions are valid at the same time. An entity-tag consists of an opaque
quoted string, possibly prefixed by a weakness indicator.
The RFC 7232 ETag header field in a response provides the entity-tag of
a selected resource. The entity-tag is an opaque identifier for versions
and representations of the same resource over time, regardless whether
multiple versions are valid at the same time. An entity-tag consists of
an opaque quoted string, possibly prefixed by a weakness indicator (see
tkrop marked this conversation as resolved.
Show resolved Hide resolved
[RFC 7232 Section 2.3](https://tools.ietf.org/html/rfc7232#section-2.3).

type: string
required: false
example: W/"xy", "5", "7da7a728-f910-11e6-942a-68f728c1ba70"
example: W/"xy", "5", "5db68c06-1a68-11e9-8341-68f728c1ba70"
tkrop marked this conversation as resolved.
Show resolved Hide resolved

If-Match:
- If-Match:
description: |
The RFC7232 If-Match header field in a request requires the server to
only operate on the resource that matches at least one of the provided
entity-tags. This allows clients express a precondition that prevent
the method from being applied if there have been any changes to the
resource.
resource (see [RFC 7232 Section
3.1](https://tools.ietf.org/html/rfc7232#section-3.1).

type: string
required: false
example: "5", "7da7a728-f910-11e6-942a-68f728c1ba70"

If-None-Match:
- If-None-Match:
description: |
The RFC7232 If-None-Match header field in a request requires the server
to only operate on the resource if it does not match any of the provided
entity-tags. If the provided entity-tag is `*`, it is required that the
resource does not exist at all.
resource does not exist at all (see [RFC 7232 Section
3.2](https://tools.ietf.org/html/rfc7232#section-3.2).

type: string
required: false
Expand Down Expand Up @@ -228,7 +229,7 @@ choose your expiration time:
----
components:
headers:
Idempotency-Key:
- Idempotency-Key:
description: |
The idempotency key is a free identifier created by the client to
identify a request. It is used by the service to identify subsequent
Expand Down
23 changes: 13 additions & 10 deletions chapters/http-requests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ An operation can be...
* [[safe, safe]]{RFC-safe} - the operation semantic is defined to be read-only,
meaning it must not have _intended side effects_, i.e. changes, to the server
state.
* [[cacheable, cacheable]]{RFC-cacheable} - to indicate that responses are
allowed to be stored for future reuse. In general, requests to safe methods
that do not depend on a current or authoritative response are cacheable.
tkrop marked this conversation as resolved.
Show resolved Hide resolved

*Note:* The above definitions, of _intended (side) effect_ allows the server
to provide additional state changing behavior as logging, accounting, pre-
Expand All @@ -234,17 +237,17 @@ intended by the operation so that it can be held accountable.

Method implementations must fulfill the following basic properties:
tkrop marked this conversation as resolved.
Show resolved Hide resolved

[cols="25%,25%,50%",options="header",]
[cols="15%,15%,35%,35%",options="header",]
|====================================================
| HTTP Method | Safe | Idempotent
| {GET} | {YES} | {YES}
| {HEAD} | {YES} | {YES}
| {POST} | {NO} | {AT} No, however you <<229>>.
zeitlinger marked this conversation as resolved.
Show resolved Hide resolved
| {PUT} | {NO} | {YES}
| {PATCH} | {NO} | {AT} No, however you <<229>>.
| {DELETE} | {NO} | {YES}
| {OPTIONS} | {YES} | {YES}
| {TRACE} | {YES} | {YES}
| Method | Safe | Idempotent | Cacheable
| {GET} | {YES} | {YES} | {YES}, but <<227>>
| {HEAD} | {YES} | {YES} | {YES}, but <<227>>
| {POST} | {NO} | {AT} No, but <<229>> | {AT} May, but <<227>>
tkrop marked this conversation as resolved.
Show resolved Hide resolved
| {PUT} | {NO} | {YES} | {NO}
tkrop marked this conversation as resolved.
Show resolved Hide resolved
| {PATCH} | {NO} | {AT} No, but <<229>> | {NO}
| {DELETE} | {NO} | {YES} | {NO}
| {OPTIONS} | {YES} | {YES} | {NO}
| {TRACE} | {YES} | {YES} | {NO}
|====================================================

[#229]
Expand Down
Loading