An idempotent request ensures that a request only affects the resource at most once. In REST all methods are idempotent except POST and PATCH.
Take the endpoint POST /api/payments that initiate a new payment charge at a payment processor. If the client experiences a network interruption during the request, how can the client safely retry the request without creating a new charge?
These are the requirements for idempotent request handling:
Require a single Idempotency-Key HTTP header for all POST and PATCH requests
Idempotency-Key value MUST be unique for a URI
Idempotency-Key value MUST NOT be reused with a different request payload
First-time requests MUST be processed normally, and the response cached
Duplicate requests MUST return the cached response
I’ve always wondered, when does this actually happen, if there is a network interruption, then the request will fail anyway from both sides, no? or is this a guarantee in systems where repeating same requests multiple times is a thing?
Okay, then if we were to treat the request as a single transaction that gets committed only if the client receives the response, then we wouldn’t need this? because at the end of the day we work over TCP and the protocol guarantees delivery.
Depending what you mean with receive response, you will need an acknowledgement that the response was received, and then what if you don’t get that and it times out? Gets to the Two Generals Problem. At some point the server must commit, and since that happens server-side you will always have a potential state where the commit occurred, but the client don’t have the acknowledgement that it happened.
In these cases you’ll want to retry the request. Works with idempotent requests like GET, DELETE, and PUT. But if you are dealing with a request that’s not idempotent like POST then you need some way to ensure the retry doesn’t create a new resource, but returns the resource that was created the first time.