Skip to content

Commit

Permalink
feat: ETags with Resource Collections (#91)
Browse files Browse the repository at this point in the history
This update introduces the addition of ETag to collection responses,
allowing clients to track versioning for individual resources within a
collection. By including an ETag for each item, we enable efficient
caching and conditional operations, reducing unnecessary API calls and
improving performance. The ETag is added as a read-only field in the
response body to ensure version consistency without altering the API's
general object model.

This solution can serve as an interim approach until a standardized
HATEOAS implementation is adopted.

---------

Signed-off-by: Travis Gosselin <[email protected]>
Co-authored-by: Vitaliy Pavlenko <[email protected]>
Co-authored-by: travisgosselin <[email protected]>
Co-authored-by: Travis Gosselin <[email protected]>
Co-authored-by: Nick Clarity <[email protected]>
  • Loading branch information
5 people committed Sep 9, 2024
1 parent 41d7ace commit a6e2f45
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
51 changes: 51 additions & 0 deletions standards/collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -626,3 +626,54 @@ GET /articles?ordering=title,-reviewRating // ordering multiple
GET /articles?orderings=title&orderings=-reviewRating // never use pluralized "orderings"
DELETE /articles?ordering=title // ordering only applies to GET methods.
```

## ETags with Collections

ETags in consideration with resource collections post some additional considerations on what the `ETag` should represent and in what granularity. For more general details about using `ETags` in request and response headers for optimistic concurrency, see the [Request Response](request-response.md#etag) section. When working with ETags in collections, the following considerations should be taken into account:

- `ETags` used in a response header **MUST** represent the entire of the response body, which is the entire collection rather than an individual resource. This is typically less useful in many situations. Working with paged collection results means the response header `ETag` is page-sensitive.
- `ETags` on a collection resource **MAY** exist both for the entire response body as a response header, and as an individual `ETag` property on each resource item in the response body if needed.
- `ETags` are best represented as metadata in headers, agnostic, or separated from the resource model representation. However, some requests to resource collections may benefit from including an `ETag` with each resource individual resource represented in the collection. Adding an `ETag` to the body of a collection response can help reduce the number of API calls by allowing clients to track changes to individual resources without needing to fetch each resource one by one to make use of request headers like `If-Match`. If using granular collection `ETags` in the response body, then:
- `ETags` **SHOULD** be added to the object model for the response body as a read-only field as a sibling to the `id` of each result item.
- `ETag` response header **MUST** be present when retrieving an individual resource.
- `ETag` property in the response body **MUST** also be present for retrieving an individual resource.
- `ETag` workflow headers, such as `If-Match`, **MUST** be available when interacting with individual resources, such as `PUT`, `PATCH` or `DELETE` requests.

```
// REQUEST
GET /resources
// RESPONSE
200 OK
Content-Type: application/json
{
"results": [
{
"id": "123",
"name": "Sample Object",
"etag": "33a64df551425fcc55e4d42a148795d9f25f89d4"
},
{
"id": "456",
"name": "Another Object",
"etag": "67b64df551425fcc55e4d42a148795d9f2567fg3"
}
]
...
}
// REQUEST
GET /resources/123
// RESPONSE
200 OK
Content-Type: application/json
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
{
"id": "123",
"name": "Sample Object",
"etag": "33a64df551425fcc55e4d42a148795d9f25f89d4"
}
```

Processing of `ETag` and associated validation headers should be consistent with the [Request Response](request-response.md#etag) section, returning appropriate status codes as needed.
1 change: 1 addition & 0 deletions standards/request-response.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ Content-Language: en-US, de-DE, en-CA

**Description**: The `ETag` response-header field provides the current value of the entity tag for the requested variant. Used with `If-Match`, `If-None-Match` and `If-Range` to implement optimistic concurrency control. Refer to `GET` request below.
- `ETag` **SHOULD** be returned for `GET` requests where the individual resource has a specific version.
- `ETags` **MAY** be returned more granularly for resource collections as described under [ETags with Collections](collections.md#etags-with-collections).

**Example(s)**:

Expand Down

0 comments on commit a6e2f45

Please sign in to comment.