Skip to content

Commit

Permalink
feat: improve guidance based on feedback (#451)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkrop committed Jan 24, 2019
1 parent 4a40c9f commit 9c9197f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 41 deletions.
54 changes: 27 additions & 27 deletions chapters/common-headers.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ questions in our daily usage, or which are useful in particular circumstances
but not widely known.

[#178]
== {MUST} Use Content Headers Correctly
== {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
Expand All @@ -33,7 +33,7 @@ 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
== {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
Expand Down Expand Up @@ -67,7 +67,7 @@ Content-Location: /products/123/images?format=raw
----

[#180]
== {SHOULD} Use Location Header instead of Content-Location Header
== {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
Expand All @@ -79,7 +79,7 @@ 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
== {MAY} Consider to Support `Prefer` Header to Handle Processing Preferences

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
Expand All @@ -102,49 +102,49 @@ components:
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
* **respond-async** is 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=<minimal|representation>** is 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
* **wait=<delta-seconds>** is used to suggest a maximum time the server
has time to process the request.
* **handling=<strinct|lenient>** used to suggest the server be strict
and report error conditions or lenient and try to continue - if
possible.
* **handling=<strinct|lenient>** is used to suggest the server to 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
{RFC7240}[RFC-7240] to indicate whether the preference was applied.
{RFC7240}[RFC-7240] to indicate whether a preference has been applied.

[#182]
== {MAY} Consider Using `ETag` Together With `If-Match`/`If-None-Match` Header
== {MAY} Consider to Support `ETag` Together With `If-Match`/`If-None-Match` Header

When creating or updating resources it may be necessary to expose conflicts
and to prevent the 'lost update' or 'initially created' problem. Following
{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.
by supporting the {ETag} header together with the {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
supposed a to respond with status code {412} - precondition failed.
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 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
expose conflicts in resource creation. If any matching entity is found, the
operation is supposed a to respond with status code {412} - precondition
failed.

The {ETag}, {If-Match}, and {If-None-Match} headers can be defined as
follows in the API definition:
The {ETag}, {If-Match}, and {If-None-Match} headers can be defined as follows
in the API definition:

[source,yaml]
----
Expand All @@ -156,12 +156,12 @@ components:
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
an opaque quoted string, possibly prefixed by a weakness indicator (see
[RFC 7232 Section 2.3](https://tools.ietf.org/html/rfc7232#section-2.3).
type: string
required: false
example: W/"xy", "5", "5db68c06-1a68-11e9-8341-68f728c1ba70"
example: W/"xy", "5", "5db68c06-1a68-11e9-8341-68f728c1ba70"
- If-Match:
description: |
Expand All @@ -174,7 +174,7 @@ components:
type: string
required: false
example: "5", "7da7a728-f910-11e6-942a-68f728c1ba70"
example: "5", "7da7a728-f910-11e6-942a-68f728c1ba70"
- If-None-Match:
description: |
Expand All @@ -192,7 +192,7 @@ components:
Please see <<optimistic-locking>> for a detailed discussion and options.

[#230]
== {MAY} Consider Using `Idempotency-Key` Header
== {MAY} Consider to Support `Idempotency-Key` Header

When creating or updating resources it can be helpful or necessary to ensure a
strong <<idempotent>> behavior comprising same responses, to prevent duplicate
Expand Down
3 changes: 2 additions & 1 deletion chapters/http-requests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,8 @@ An operation can be...
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.
are cachable, if it does not require a current or authoritative response
from the server.

*Note:* The above definitions, of _intended (side) effect_ allows the server
to provide additional state changing behavior as logging, accounting, pre-
Expand Down
20 changes: 7 additions & 13 deletions chapters/performance.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Common techniques include:
<<157>> below)
* {ETag} and {If-Match}/{If-None-Match} headers to avoid re-fetching of
unchanged resources (see <<182>>)
* {Prefer} header with `return=minimal` or `respond-async` to anticipate reduced
processing requirements of clients (see <<181>>)
* <<pagination>> for incremental access of larger collections of data items
* caching of master data items, i.e. resources that change rarely or not
at all after creation (see <<227>>).
Expand Down Expand Up @@ -174,7 +176,8 @@ Caching has to take many aspects into account, e.g. general <<cacheable,
cacheability>> of response information, our guideline to protect endpoints
using SSL and <<104, OAuth authorization>>, resource update and invalidation
rules, existence of multiple consumer instances. As a consequence, caching is
in best case complex, in worst case inefficient.
in best case complex, e.g. with respect to consistency, in worst case
inefficient.

As a consequence, client side as well as transparent web caching should be
avoided, unless the service supports and requires it to protect itself, e.g.
Expand Down Expand Up @@ -246,6 +249,7 @@ components:
type: string
required: false
example: "private, must-revalidate, max-age=300"
- Vary:
description: |
The RFC 7231 Vary header field in a response defines which parts of
Expand All @@ -258,20 +262,10 @@ components:
type: string
required: false
example: "accept-encoding, accept-language"
- ETag:
description: |
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
[RFC 7232 Section 2.3](https://tools.ietf.org/html/rfc7232#section-2.3).
type: string
required: false
example: W/"xy", "5", "5db68c06-1a68-11e9-8341-68f728c1ba70"
----

*Hint:* For {ETag} source see <<182>>.

The default setting for {Cache-Control} should contain the `private` directive
for endpoints with standard <<104, OAuth authorization>>, as well as the
`must-revalidate` directive to ensure, that the client does not use stale cache
Expand Down

0 comments on commit 9c9197f

Please sign in to comment.