Card 06/ 10
Repeat Example: Sending PUT, PATCH and POST Twice
One order, three writes, each sent twice after a timeout; only one of them leaves the order as intended.
Idempotency, applied to three writes on one order, decides which retries are harmless. Order 42 holds one item, a book. A client sends each write below, gets no reply because of a timeout, and sends it again; both copies reach the server. Before reading the trace, predict the order's state after each second request. The run is illustrative.
InputOrder 42 starts with items [book]; each request is sent twice
PUT /orders/42 with items [book, pen]
- [book, pen]
- [book, pen]same
The second PUT stores the same complete order again.
PATCH /orders/42, JSON Patch: add pen to the end of items
- [book, pen]
- [book, pen, pen]changed
Each copy appends, so the second adds another pen.
POST /orders with a new order for a pen
- order 43 created
- order 44 createdchanged
Each POST asks the collection to create an order.
ResultOnly the PUT left the server as the client intended. The PATCH added a second pen, and the POST created two orders.
Why the PUT was harmless. It described the final state, the whole item list, so applying it again changes nothing. The client could have retried ten times.
Why the PATCH was not. It described an action, "append", not a state. Had it been a merge patch that set items to [book, pen], it would have behaved like the PUT. The method was the same; the content decided.
Why the POST was not. Each POST is a new request to create, and the server has no way to know the second is a copy of the first. A customer sees two orders, and possibly two charges.
The lesson is to write retryable operations as states rather than actions where the design allows it, and to give the ones that must stay actions, such as creating a payment, a way for the server to recognise a repeat.
← → move through sections and cards