Explain idempotency in API design.
HTTP methods: what each verb promises
A method's promise about safety and idempotency decides when a retry is safe, when a cache is legal, and PUT versus POST.
For this question · chapter 3 of 3
POST keeps adding, PUT stays
- The server keeps a count of users, and right now that count is 0. That count will change here, and how it changes depends on the operation the client sends.
- A POST request to /users reaches the server. The server picks the id itself, in this case 41, and the user count becomes 1. One request created one user, as expected. Now the server sends the reply back to the client.
- The reply is lost halfway back across the network, so the client receives nothing. Now the client has two possible explanations. Either the reply was lost on the way back, or the request itself failed. In both cases the client receives nothing, so the client cannot tell them apart.
- The client does not know what happened, so it sends the same request again. The server handles this second request and creates user 42, so the count of users rises to 2. The server treated the two as separate requests, because nothing in the second request marked it as a repeat. Both requests were valid POSTs.
- One more retry creates user 43. The server now holds three users, and the caller wanted only one. Replace users with charges, and the same retries charge a customer three times. POST makes no promise against duplicates, so POST is not idempotent.
- The client sends a PUT request to /users/123. The client chose that address itself, so the server only acts on the one record at that address. The network is no better than before. But the address now names one record instead of a collection, and that change alone makes the retry safe.
- The reply is lost again, so the client retries two more times. Each retry writes the same record with the same body. The count stays at 1. The server did the work three times, but the state after three calls is the same as the state after one. Repeating the call changed nothing, so the call is idempotent.
- A charge cannot be a PUT, because the client has no id to set. So the client sends POST /charges with an Idempotency-Key header, 9f2, and retries twice under the same key when the reply is lost. The server stored its first response under that key, so every repeat gets that same response and the charge count stays at 1. Stripe uses this mechanism and keeps each key for 24 hours.
The server keeps a count of users, and right now that count is 0. That count will change here, and how it changes depends on the operation the client sends.
A method is a promise about two things. Does the call change state, and does calling again change anything more? That promise decides when a retry is safe, when a cache may keep the answer, and PUT versus POST. Pick the verb whose promise matches the work, and protect POST with a key that detects a repeat.
© LearnThatStack - diagrams may not be republished without permission.
Want a quick review of the fundamentals? See the API Design cheatsheet.
74 of 92 API Design answers are in Pro.
Full answers, code samples, and AI explanations that go simpler or deeper. Cancel anytime.
- Full answers + code
- AI explanations, simpler or deeper
- 1,000 AI credits / month
- Cancel anytime