From 561b2beb6ddad5db26390f20385412920a67bb0c Mon Sep 17 00:00:00 2001 From: nicholas-s-perkins Date: Wed, 11 Dec 2024 18:21:33 -0600 Subject: [PATCH] Improved Idempotency-Key description. --- standards/request-response.md | 39 +++++++++++------------------------ 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/standards/request-response.md b/standards/request-response.md index 7d6dd34..0f46e9e 100644 --- a/standards/request-response.md +++ b/standards/request-response.md @@ -444,25 +444,23 @@ Access-Control-Allow-Methods: *
-```note -**KEEP AN EYE ON IT**: The [Idempotency-Key Request header](https://tools.ietf.org/id/draft-idempotency-header-01.html) is in an experimental state but getting lots of attention as a pattern of making fault-tolerant resilient requests for traditionally non-idempotent methods like `POST`. -``` +#### [Idempotency-Key Request header](https://datatracker.ietf.org/doc/html/draft-idempotency-header-01) +**Type**: Request -#### Idempotency-Key -The HTTP Idempotency-Key request header field can be used to carry an "idempotency key" to make non-idempotent HTTP methods such as POST or PATCH fault-tolerant. -This is both a standard and non-standard header, as there is common usage of it, but no accepted spec for it. +**Support**: OPTIONAL +**Description**: +The HTTP Idempotency-Key request header field can be used to carry an "idempotency key" to make non-idempotent HTTP methods such as POST or PATCH fault-tolerant. +This is an experimental header, as there is common usage of it, but no accepted spec for it. `Idempotency-Key` should typically be a V4 UUID as a string, or another random string with enough entropy to avoid collisions, and should be no longer than 255 characters long. -A suggested regex for a generic validator: -```regexp -[a-z0-9-]{20,255} -``` -An API must in some way persist the Idempotency-Key in a stateful way. +An API must in some way persist the Idempotency-Key in a stateful way to manage the idempotency. It is common to include the key as part of the primary key or as a secondary index for the resource. -An API, when faced with a conflict, may return any standard success `2xx success` if the endpoint is idempotent, -or a `409 Conflict` if the endpoint is not idempotent. +- The header value **MUST** follow this regex format: `[a-z0-9-]{20,255}` +- An API **MUST** return a `400` when the header value is an invalid format. +- On conflict, an API **MUST** return a `2xx` if the endpoint is idempotent, or a `409` if the endpoint is not idempotent. +- An API **MAY** treat this as the final primary ID of the resource, or as some part of the ID. ``` // CORRECT @@ -471,22 +469,9 @@ Idempotency-Key: d4f885c5-2196-49c0-ba69-bc70008585ad-custom // INCORRECT Idempotency-Key: a // not enough entropy -Idempotency-Key: KG5Lxw!@#$&*()FBepaKHyUD // special characters can be limiting for storage and url reference +Idempotency-Key: KG5Lxw!@#$&*()FBepaKHyUD // non-url-safe special characters can be limiting for usage or later reference ``` -This is a common technique for avoiding retry-loops creating duplicate entries. -For example: -1. User calls API (Idempotency-Key=d4f885c5-2196-49c0-ba69-bc70008585ad) -2. API creates resource(key=d4f885c5-2196-49c0-ba69-bc70008585ad) -3. API responds 201 -4. Response dies in transit, user receives 5xx -5. User calls API again (Idempotency-Key=d4f885c5-2196-49c0-ba69-bc70008585ad) -6. API notices resource(key=d4f885c5-2196-49c0-ba69-bc70008585ad) exists, responds with a 201 - -It is also a powerful technique to bind a workflow to an idempotency key to avoid duplicate entries or breakage. -`Idempotency-Key` can be bound to various message IDs for a system, ensuring that if the message is replayed, -the stateful interactions are all idempotent to that message ID. - ### Custom Headers - Custom Headers **MAY** be used and created as necessary.