4 ms·
Curious that they don’t mention HTTP conditional requests [1] even in passing. This mechanism is typically used for slightly different things, but you can, for
by vfaronov 10y ago
Curious that they don’t mention HTTP conditional requests [1] even in passing. This mechanism is typically used for slightly different things, but you can, for example, make a PATCH request “idempotent” (in their sense) by adding an If-Match header to it. I’d say that Idempotency-Key itself may be considered a precondition and used with status codes 412 [2] and 428 [3].
By the way, WebDAV extended this mechanism with a general If header [4] for all your precondition needs. I’m kinda glad it didn’t catch on though...
[1] https://tools.ietf.org/html/rfc7232 https://tools.ietf.org/html/rfc7232
[2] https://tools.ietf.org/html/rfc7232#section-4.2 https://tools.ietf.org/html/rfc7232#section-4.2
[3] https://tools.ietf.org/html/rfc6585#section-3 https://tools.ietf.org/html/rfc6585#section-3
[4] https://tools.ietf.org/html/rfc4918#section-10.4 https://tools.ietf.org/html/rfc4918#section-10.4
- brandur 10y ago(I wrote this.) It's always a bit of a fine line as to what makes the final cut in this sort of article (I tried to stay on message without getting too off track), but HTTP conditional requests are definitely something that could have been a good fit. I should point out though that using `ETag`/`If-Match` generally has a slightly different use on updates compared to Stripe's `Idempotency-Key`. A server sends back an `ETag` that's correlated to the current state of a resource, and clients make conditional requests using one so that they can get a guarantee that they're not changing state where they didn't expect to. Because every HTTP request stands by itself, it's very possible for a client to fetch a resource and go to update it on a second request only to accidentally clobber changes that were made by a different client. It's this sort of "mid-air collision" that `ETag`/`If-Match` help to avoid. Mozilla's documentation on the subject is quite good: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ET...
- smallnamespace 10y agoIf you interpreted 'current state of a resource' somewhat liberally, where the resource is the abstract state of a particular versioned/timestamped request, does an ETag then really become the same as an Idempotency-Key? Or put another way, is the only difference that ETags are generally computed based on the server's stored state of a particular resource so it's possible to have multiple clients with the same ETag, while the 'resource' backing an Idempotency-Key is the entire state of a particular user that encompasses all the user's resources?
- brandur 10y agoSo I think that you could absolutely patch a system that's quite similar to `Idempotency-Key` into `ETag`, but you might be pushing the original concept far enough base to the point where you're not gaining much by doing so. Using `If-Match` is essentially indicating that you want to make a request conditionally as long as the server's state matches a nonce that you're holding. Presumably that nonce was handed to you already by the server on an initial request that you already executed. You can hand Stripe's API an `Idempotency-Key` on the first request that you make against it. Furthermore, you'd never say that the first request made in this way was meant to be conditional, even if subsequent retries (after an initial failure) might be. I think it wouldn't be a problem in practice to just retrofit `ETag` to do the same thing, but doing so is (arguably) semantically wrong, and I think there's something to be said for the clarity that just using your own header with an obvious name like `Idempotency-Key`. I'm open to be persuaded though :)