HTTP / LESSON 05

Safe and idempotent methods

Find out which requests can be repeated safely, and why that matters when networks fail.

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 PUT and DELETE really are idempotent.
  • Decide what clients should do when a POST times 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 PUT with {"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, and OPTIONS are safe. PUT and DELETE are idempotent but not safe. POST is neither.
  • Idempotence is about the effect, so the response can differ.

Next, we'll look at status codes, which tell you what happened.