Part 2 of 8 · 3 min read
Methods and status codes
The five common methods, the one idea that decides whether a retry is safe, and what to do about each status code.
Methods and idempotency
The method says what the client wants to do. Five are common:
| Method | Use | Safe to repeat? |
|---|---|---|
GET |
Read data | Yes |
POST |
Create something or run an action | No, unless you use an idempotency key |
PUT |
Replace something | Yes |
PATCH |
Change part of something | Not guaranteed |
DELETE |
Remove something | Yes (the second call finds nothing) |
"Safe to repeat" is the important column. Imagine you ask a server to charge a card, and your connection drops before you see the answer. Did the charge happen? You do not know. If you simply ask again and the first one went through, the customer is charged twice.
Idempotent
An operation is idempotent if doing it several times has the same effect as doing it once. Setting a value to 5 is idempotent. Adding 1 to a value is not. This is the property that makes a retry safe. GET, PUT and DELETE are meant to be idempotent. A POST that charges a card or sends an email is not.
Idempotency key
A unique label that you attach to a request (many APIs read it from a header named Idempotency-Key). If the server sees the same key twice, it does the action once and returns the same answer for both. This makes it safe to retry even a POST. You create the key once, before the first attempt, and send the same one on every retry.
Check yourself
- Why is it fine to retry a
GETbut dangerous to blindly retry aPOSTthat sends an email? - What does an idempotency key let the server do?
Status codes: what to do
The first digit of the status code tells you the family. What matters for your code is your reaction.
| Code | Meaning | What your code should do |
|---|---|---|
| 200, 201, 204 | Success | Use the result |
| 400, 422 | The request is wrong | Do not retry. Fix the request. For model APIs, log the message |
| 401 | Not authenticated (missing or bad key) | Do not retry. Check the key |
| 403 | Authenticated but not allowed | Do not retry |
| 404 | Not found | Do not retry |
| 408 | Request timed out | Retry |
| 409 | Conflict | Depends. Read the message |
| 429 | Too many requests | Wait (obey Retry-After), then retry |
| 500 | Server bug | Retry a few times |
| 502, 503, 504 | Server or gateway overloaded or down | Retry with backoff |
Rule of thumb
4xx means you did something wrong, so repeating the same request will not help (except 429 and 408). 5xx means the server had a problem, so a later attempt may succeed.
Here is a real 404 from the same test server:
$ curl -i -s http://127.0.0.1:8765/nope
HTTP/1.0 404 Not Found
Content-Type: application/json
Content-Length: 22
{"error": "not found"}
curl -i shows the response headers too, and -s hides the progress meter. Notice that even an error carries a body. Read it: good APIs put the reason there.
A 429 deserves one more explanation. It means you are sending requests faster than the server allows. The server may add a Retry-After header that says how many seconds to wait. Obeying it is both polite and the fastest way to get through.