Earlier quoted context omitted.
GET is not supposed to make changes on the server. The usual idempotent verbs for making changes are PUT and DELETE. One thing that's confusing, here, is that idempotency only applies for the same request, but the article implies that idempotency is about whether the request contains a specific "idempotency key". Don't do that, and this problem evaporates.
> Don't do that, and this problem evaporates. Don't do that, and you solved nothing. Either I'm missing what you mean, or half the comments here are missing the point of idempotency. Let's say your server received this request twice within one minute: { items: [ { id: 123, amount: 1 } ], creditCardInfo: { ... } } How can you tell from the server if that's a retry (think e.g. some reverse proxy crashed and the first r…
Idempotency is easy until the second request is different
111–120 of 244 posts
Re: Idempotency is easy until the second request is different
#112Earlier quoted context omitted.
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.
Even if you have a complex long-running multistep orchestration problem, you can break it down into simpler transactions. Eg you could start with a "lock the resources" txn.
But 99% of these conversations around idempotence are simple POST operations like "create order" that regular old database concurrency management handles just fine.
Re: Idempotency is easy until the second request is different
#113Earlier quoted context omitted.
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.
That's usually solved with traditional database transactions. Even if you have a complex long-running multistep orchestration problem, you can break it down into simpler transactions. Eg you could start with a "lock the resources" txn. But 99% of these conversations around idempotence are simple POST operations like "create order" that regular old database concurrency management handles just fine.
That doesn't answer my question. What response do you return to the client in the case I described?
Re: Idempotency is easy until the second request is different
#114Earlier quoted context omitted.
That's usually solved with traditional database transactions. Even if you have a complex long-running multistep orchestration problem, you can break it down into simpler transactions. Eg you could start with a "lock the resources" txn. But 99% of these conversations around idempotence are simple POST operations like "create order" that regular old database concurrency management handles just fine.
> That's usually solved with traditional database transactions. That doesn't answer my question. What response do you return to the client in the case I described?
Re: Idempotency is easy until the second request is different
#115Earlier quoted context omitted.
That's usually solved with traditional database transactions. Even if you have a complex long-running multistep orchestration problem, you can break it down into simpler transactions. Eg you could start with a "lock the resources" txn. But 99% of these conversations around idempotence are simple POST operations like "create order" that regular old database concurrency management handles just fine.
> That's usually solved with traditional database transactions. That doesn't answer my question. What response do you return to the client in the case I described?
So one will complete with 200, one will complete with 409. It doesn't matter which.
That said, there's something odd about the way you phrased this question. If the original request hasn't gotten a response yet, why is it sending a retry? What you're asking is more general: What happens when two conflicting requests come in? This is something we've been solving with RDBMSes since the 1970s.
Re: Idempotency is easy until the second request is different
#116Earlier quoted context omitted.
> Don't do that, and this problem evaporates. Don't do that, and you solved nothing. Either I'm missing what you mean, or half the comments here are missing the point of idempotency. Let's say your server received this request twice within one minute: { items: [ { id: 123, amount: 1 } ], creditCardInfo: { ... } } How can you tell from the server if that's a retry (think e.g. some reverse proxy crashed and the first r…
In the case of a PUT or DELETE, the key is in the URI. /custs/12345/orders/20260510T153023.239 for example.
I mean: you still have the problem regardless of following HTTP verb semantics or not.
Re: Idempotency is easy until the second request is different
#117Earlier 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").…
Re: Idempotency is easy until the second request is different
#118Like, I thought the entire definition had to do with "the exact same thing twice."
Re: Idempotency is easy until the second request is different
#119This 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.
Re: Idempotency is easy until the second request is different
#120This 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;…
However, it's good for e-commerce where there are a subset of "important" operations, but I'd argue the idempotency key is better for a financial API like Stripe where the majority of your operations need these semantics.
You also run into a problem if PUT/PATCH needs to be exactly-once instead of at least once. Not as common, but again, might be something you run into with a financial API.