Live data from Hacker News

Idempotency is easy until the second request is different

blog.dochia.dev

101–110 of 244 posts

Re: Idempotency is easy until the second request is different

#101

This is all way too much. If you see a duplicate idempotency key, skip the replay and always return 409. This becomes a client problem. Clients already need to help enforce idempotent contracts; "check for conflict response" is not an onerous imposition. I've built multiple ecommerce APIs with this approach and they work great. No heroic measures required. You can often satisfy this contract with a unique constraint;…

But that's not idempotent? If I'm a client and I don't know if the original request went through, getting a 409 on any subsequent requests tells me nothing about whether the original request was successful or not.

The 409 should come with an id or a url the client can use to find the original result.

Re: Idempotency is easy until the second request is different

#102
Sigh. What this article is badly saying is that they really don't understand the difference between a *transaction* versus idempotency.

You want a rebuildable environment after testing blows it up? Idempotent build scripts.

You want to sell crap from a web interface? Thats a transaction. If you do 'repeat a sale', thats a new transaction, with new goods, with newer date.

Forcing 1 paradigm on a different one always results in gnashing of teeth and sadness. But I guess it gets the blog hits for that dopamine rush.

Re: Idempotency is easy until the second request is different

#103
post #48

Don't fix other people problems. If idempotent key was seen then send back response. Clients intention is outside the scope. If contract says "idempotency on key" the idempotent response on key. If contract says "idempotent on body hash" then response on body hash (which might or might not include extra data). APIs are contracts. Not the pinky promise of "I'll do my best guess"

APIs always have unspecified edge cases (for any sufficiently complex API). In those cases, the API usually does the author's best guess of the proper behavior.

Re: Idempotency is easy until the second request is different

#104

Earlier quoted context omitted.

But that's not idempotent? If I'm a client and I don't know if the original request went through, getting a 409 on any subsequent requests tells me nothing about whether the original request was successful or not.

The 409 should come with an id or a url the client can use to find the original result.

...and if you're using the approach of "let the client pick ids", you don't even need that. The client has everything it needs.

Re: Idempotency is easy until the second request is different

#105
I will add: if you have an operation that adds a record to a database (like a payment in the OP example), don’t forget to have some field that the client specifies that can be used to find and query the status of that record later. This field can be the idempotency key itself or another field.

Or you can completely forget this feature and make it really awkward for the client to reconcile their view of the world with yours and/or to check in the request later. cough Mercury cough.

It is, just barely, acceptable to generate the identifier server side and return it to the client.

Re: Idempotency is easy until the second request is different

#106

This is all way too much. If you see a duplicate idempotency key, skip the replay and always return 409. This becomes a client problem. Clients already need to help enforce idempotent contracts; "check for conflict response" is not an onerous imposition. I've built multiple ecommerce APIs with this approach and they work great. No heroic measures required. You can often satisfy this contract with a unique constraint;…

But that's not idempotent? If I'm a client and I don't know if the original request went through, getting a 409 on any subsequent requests tells me nothing about whether the original request was successful or not.

Retries will only receive 409 if the original request was successful. If the original request failed, the server performs the operation as normal on the second request. It doesn't replay failures.

The whole point of the idempotence mechanism is so you can make a reliable distributed system. If the first try fails, the client doesn't know if it succeeded or not, so the client should try again later ("at-least-once"). The idempotence mechanism just ensures that we don't get duplicates in the case that the first try actually succeeded.

If you replayed failures there wouldn't be any point to the idempotency key.

Re: Idempotency is easy until the second request is different

#107
Why does a second request need to replay the response? It seems to solve a ton of issues to just send back "request key already used" regardless of whether the request is the same or whether the previous request succeeded or failed. Is there a common situation where the replay is needed? I think of idempotency being important to deal with caching and the like, not something you should build your client around.

Re: Idempotency is easy until the second request is different

#108
Idempotency is just the next generation realizing that goto and global variables are still antipatterns.

And then some lazy birdbrain will come up with some new way to either jump to a random place in the code without guardrails on program state, or referencing data that other code or threads could have touched, and they'll call it a time saving feature.

And then we will all learn the hard way that those annoying restrictions were in place for a reason.

This is the great circle of life and death and rebirth

Re: Idempotency is easy until the second request is different

#109

Earlier quoted context omitted.

But that's not idempotent? If I'm a client and I don't know if the original request went through, getting a 409 on any subsequent requests tells me nothing about whether the original request was successful or not.

Retries will only receive 409 if the original request was successful. If the original request failed, the server performs the operation as normal on the second request. It doesn't replay failures. The whole point of the idempotence mechanism is so you can make a reliable distributed system. If the first try fails, the client doesn't know if it succeeded or not, so the client should try again later ("at-least-once").…

What if the original request is still being processed when the retry comes in? That doesn't fall into either of your categories: the request isn't successful, but it hasn't failed either.

Re: Idempotency is easy until the second request is different

#110

Earlier quoted context omitted.

The 409 should come with an id or a url the client can use to find the original result.

...and if you're using the approach of "let the client pick ids", you don't even need that. The client has everything it needs.

[deleted]
Post reply on HN