Hacker News new | ask | show | jobs
by mrkeen 44 days ago
In what sense is GET naturally idempotent?

The GET/POST split is the defence (even it's only advisory).

GET-only means every time you hit the back button during an order flow, you might double-order.

1 comments

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 request timed out, but the payment already went through to the user's CC)... or if the user just trying to purchase another item 123 because they forgot they needed 2?

There is simply no way to make the requests idempotent without an idempotency key. The only way to tell both situations apart is to key the requests by some UID. The HTTP verb is irrelevant.

Did I misunderstand what you meant?

In the case of a PUT or DELETE, the key is in the URI. /custs/12345/orders/20260510T153023.239 for example.
Yes, I understand that, but I'm not sure how that changes anything?

I mean: you still have the problem regardless of following HTTP verb semantics or not.

In the case in the article, the request is being rebuilt again by the client, and may be slightly different. Typically, the server doesn't have to care about any of that if it's just "did we get something for this ID?" and either it did and errors (could be a 4xx or a 5xx depending on what it now has), or it didn't, and processes the request.
So what you propose is first you create the request payload and POST it, which generates a request-id-bound URL (but it does nothing stateful yet) and then you actually request to perform it? Because otherwise I don't see any difference.