Networks fail. Sometimes a client sends a request and the connection drops before the response arrives. Did the request work? The client can't tell. Can it send the request again?
The answer depends on the method.
Two properties
- Safe: the client isn't asking for anything to change on the server.
- Idempotent: sending the request many times has the same intended effect as sending it once.
| Method | Safe | Idempotent |
|---|---|---|
GET, HEAD, OPTIONS |
Yes | Yes |
PUT, DELETE |
No | Yes |
POST, PATCH |
No | No |
Each safe method is also idempotent: if nothing changes, repeating it changes nothing. PATCH isn't idempotent in general, though a particular PATCH can be.
Let's test these with the Contacts API.
POST twice
Press Run on this cell twice.
You get two contacts with two different ids. POST isn't idempotent, so each request has a new effect.
Think: Imagine that this request creates a payment. What happens if the client retries it after a timeout?
PUT twice
Use one of the ids you just created in place of 128. Run this cell twice.
Both responses are the same, and the contact ends up in the same state. Sending it again does no harm.
DELETE twice
Run this cell twice, again with your own id.
The first response is 204, and the second is 404. The responses differ, but DELETE is still idempotent. Idempotence is about the effect on the server, not the response: after one request or two, the contact is gone.
Your turn: Delete the other contact you created with
POST.
These are promises
The server has to keep these promises. HTTP can't enforce them. Imagine an API with this URL:
GET /deleteContact?id=123
HTTP allows the request, but this API breaks the promise that GET is safe. Tools everywhere rely on that promise:
- Browsers fetch links ahead of time, to load pages faster.
- Search engines follow every link they find.
- Caches and proxies can repeat or skip a
GET. - HTTP clients can retry idempotent requests on their own.
Any of them could delete that contact, without anyone meaning to.
Designing with these in mind
When you design an API:
- Never change anything in response to a
GET. - Make sure that
PUTandDELETEreally are idempotent. - Decide what clients should do when a
POSTtimes out. We'll come back to this in a later chapter.
Discuss: Your API has an operation that adds 100 rupees to a wallet. Would you use
PUTwith{"add": 100}? What would you do instead?
Summary
- Safe methods ask for no changes. Idempotent methods can be repeated with the same intended effect.
GET,HEAD, andOPTIONSare safe.PUTandDELETEare idempotent but not safe.POSTis neither.- Idempotence is about the effect, so the response can differ.
Next, we'll look at status codes, which tell you what happened.