ietf-wg-httpapi / idempotency

Repository for "The Idempotency-Key HTTP Header Field"
Other
17 stars 10 forks source link

Clarify "resource server SHOULD respond with the result of the previously completed operation" #48

Open darrelmiller opened 1 week ago

darrelmiller commented 1 week ago

[Without chair hat]

The current draft contains the following text:

Duplicate request (idempotency key and fingerprint has been seen)

Retry

The request was retried after the original request completed. The resource server SHOULD respond with the result of the previously completed operation, success or an error. See Error Scenarios for details on errors.

https://ietf-wg-httpapi.github.io/idempotency/draft-ietf-httpapi-idempotency-key-header.html#section-2.6

Concerns were raised about the ambiguity of this text https://github.com/ietf-wg-httpapi/idempotency/issues/31#issuecomment-2010735489

If we can accept the premise that the goal of the idempotency key is to enable POST and PATCH to be idempotent as defined by RFC9110 https://www.rfc-editor.org/rfc/rfc9110.html#section-9.2.2 like PUT/DELETE, then we can use the behaviour of those existing idempotent methods to guide us in defining the correct behaviour for idempotent POST/PATCH.

If a PUT request fails with a transient error such as 503/504, then a subsequent request has no expectation of always receiving the same response. Even a successful DELETE that gets a 204, has no expectation of another 204 on the second request. It will commonly return a 404.

Let me propose alternate text for consideration

The request was retried after the original request completed. The resource server SHOULD respond with a response consistent with the request being completed according to the user's intent. See Error Scenarios for details on errors.

Acconut commented 5 days ago

If we can accept the premise that the goal of the idempotency key is to enable POST and PATCH to be idempotent as defined by RFC9110 https://www.rfc-editor.org/rfc/rfc9110.html#section-9.2.2 like PUT/DELETE, then we can use the behaviour of those existing idempotent methods to guide us in defining the correct behaviour for idempotent POST/PATCH.

[..]

Let me propose alternate text for consideration

The request was retried after the original request completed. The resource server SHOULD respond with a response consistent with the request being completed according to the user's intent. See Error Scenarios for details on errors.

From the perspective of someone consuming an API with support for idempotency, it would be easier if the server responds with the same responses when a request is being retried and when a request is handled for the first time. The one does not have to consider the possibility of different status codes or response headers, simplifying application logic and avoiding bugs where responses from retried requests are not correctly handled. Replaying responses for retried requests would be easier for clients.

That being said, replaying responses does not seem to be the intention behind how RFC 9110 defines idempotency. If the goal of this draft is to achieve idempotency as defined in RFC 9110, then your proposed text is the right direction.

jmileham commented 1 day ago

I agree with @Acconut that the preferable approach as an API client would be for the server to respond with a consistent response code on retry, and I'd even extend it to interactive use. Even web browsers could benefit from a well defined consistent response behavior upon completion as well, in my opinion, enabling generalized double-click protection.

My pitch in the other issue on this topic was to codify that 4xx client-error be considered "non-completed" (which differs from Stripe's implementation), such that a retry with the same idempotency key would be applicable, if valid, rather than considered permanently "completed and failed." Not sure whether that is something this spec wants to address.