Hacker News new | ask | show | jobs
by WilcoKruijer 44 days ago
I really hate the POST verb for RESTish APIs because it cannot be idempotent without implementing an idempotency layer. Other verbs are naturally idempotent. Has anyone tried foregoing POST routes entirely? Theoretically you can let the client generate an ID and have it request a PUT route to create new entities. This would give you a tiny amount of extra complexity on the client, but make the server simpler as a trade-off.
1 comments

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.

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.