HTTP methods — The safe and idempotent promises
Choose between GET, POST, PUT, DELETE, and HEAD by 'what you want done', draw the line with the promises of safe (does not change server state) and idempotent (same result however many times), and use them for retry decisions.
Are you building everything with "just POST it"?
Forms, retrieval, deletion — everything built as POST because it works. Or the reverse: a re-clicked submit button registers an order twice and nobody can find the cause. Method choice is knowledge that lets you get away with vagueness while things merely work — and then bites after the accident happens.
As read in the previous chapter, the method at the front of the request line is the verb of the correspondence. HTTP has many methods, but being able to choose among these five is enough to start.
For example, PUT /users/42/profile says "make user 42's profile exactly this content", while POST /orders says "process this order data and create a new order". A replacement with a fixed destination is PUT; something newly born or a processing request is POST — that is the basic division.
Practice 2-1 — Choosing among the five verbs
Practice picking the right method from 'what you want done'.
Q1. At the online shop https://shop.example.com, when submitting the contents of an order form to create a new order, which method is most appropriate?
A favor of the kind 'create something new / process this content' is POST. GET carries the promise of retrieval only, never changing server state, and is not used to send content like order data in a body. HEAD is a body-less check and DELETE is a deletion request — neither can create an order.
Q2. For a huge video file, you want to know only its size and last-modified time without downloading it. Which method is most appropriate?
HEAD asks for 'the same answer as GET, minus the body'. The server returns only headers (Content-Length, Last-Modified, and so on), so you can check metadata without shipping a huge body. GET would also give the information but would transfer the body too — far too wasteful for the purpose.
Q3. Which best describes the difference between PUT and POST?
PUT is a 'save-and-overwrite' aimed at a specified URL: sending the same request twice leaves the same final state as sending it once. POST is a 'request for processing', so sending it twice can create two orders — its effects can pile up per execution. This difference is the 'idempotent' line drawn in the next practice set, and has nothing to do with encryption, data format, or HTTP version.
Two promises — safe and idempotent
More important than memorizing five verbs are the two promises tied to methods. These two words appear constantly in specifications and in error investigations.
Let us verify this hands-on. Send PUT /users/42/profile replacing the profile with "name = Komura" three times, and the final state is "name = Komura" — the same as once. Send DELETE /orders/7 twice, and the final state — order 7 is gone — is the same (the second call may return 404, but idempotency looks at the server's final state). Meanwhile, send POST /orders three times and three orders exist — POST is not idempotent.
Putting the relations in order: safe always implies idempotent (changing nothing means the result is the same however many times). The converse does not hold — PUT and DELETE sit in the middle band of "changing, but the same however many times": idempotent yet not safe.
A map of the five methods laid out on the two axes of safe and idempotent. GET/HEAD keep both promises, PUT/DELETE only idempotency, and POST makes neither promise. This map becomes your decision table for "may I retry?".
Where it pays off in practice — check idempotency before retrying an update
Where these two promises pay off most in practice is the decision to resend (retry) after a communication failure.
When a request times out, there are actually two possibilities: "the request never reached the server", or "it arrived and was fully processed, and only the reply was lost" — and from the client side you cannot tell them apart. This is where idempotency does its work.
This is exactly why browsers go out of their way to ask "Resubmit form?" when you reload a POST result page (a scene that reappears in the Chapter 7 cases). It is also why most libraries with built-in automatic retry resend only GET by default — this promise is the justification. "Before retrying an update, check whether the method is idempotent" — repeat it until your hands remember.
Practice 2-2 — Drawing the line between safe and idempotent
State the two promises precisely and tie them to the practical question of 'may I retry?'.
Q4. What promise does it express for a method to be 'safe'?
Safe = the promise of 'read-only, changing no server state' — GET and HEAD qualify. It is not a guarantee of encryption (that is TLS's job), speed, or freedom from errors. This promise is exactly why search-engine crawlers can follow links with GET without worry — a design where a GET deletes a product has broken this promise.
Q5. Which pair of methods is 'idempotent but not safe'?
PUT (replacement with the same content) and DELETE (deletion of the same thing) change server state, so they are not safe, but running them twice leaves the same final state as once, so they are idempotent. GET and HEAD are safe (they change nothing), and since they change nothing they are naturally idempotent too. POST is the archetype of neither safe nor idempotent. The inclusion 'safe ⊂ idempotent' is a tidy way to remember it.
Q6. You sent an update API request and it timed out with no response. Before sending the same request again, which is the most appropriate thing to check?
The scary part of a timeout is the possibility that 'the request reached the server and was fully processed, and only the reply was lost'. With idempotent PUT/DELETE, even if it was processed, resending does not change the outcome — you can resend with confidence. Resending a POST can double an order or a payment, so you resend only after confirming whether it was processed, or on top of a duplicate-prevention mechanism. 'Check idempotency before retrying an update' — the most practically useful sentence in this chapter.
What to take from this chapter
- The method is the verb of the correspondence. Retrieval is GET, a body-less check is HEAD, processing requests and creation are POST, replacement at a stated destination is PUT, deletion is DELETE
- Safe = does not change server state (GET/HEAD). Idempotent = same final state however many times (GET/HEAD/PUT/DELETE). Safe always implies idempotent
- POST is neither safe nor idempotent. Unconditional retries after a timeout risk duplicate processing
- Check idempotency before retrying an update — the sentence that pays off in practice
Now that you can read the asking side, the next chapter turns to the other half of the correspondence — the server's reply. We decode the 3-digit status codes, starting from the hundreds digit.