Methods are a contract, not a label
Safe, idempotent, cacheable. Three properties that decide what browsers, proxies and retrying clients are allowed to do to your endpoint.
GET and HEAD are safe: they must not change anything the caller would mind changing. That is not a style rule. Browsers prefetch links, corporate proxies scan them, and crawlers follow them, so a GET /delete?id=7 is a URL that a security scanner will eventually fire and a link preview may fire first. People have lost data to exactly this.
Idempotent means doing it twice has the same effect as doing it once. PUT and DELETE are meant to be idempotent; POST is not. This is what makes retries safe or unsafe, and retries are not optional: clients retry, load balancers retry, and users mash buttons on flaky connections. If your PUT /orders/42 sets a state it is idempotent; if it appends a line item it is not, and you have mislabelled it.
PATCH is the one people get wrong. It is a request to apply a described change, which means the body should describe a change rather than be a smaller version of the resource. Sending a partial object is common and workable, but you have to decide explicitly what a missing key means: leave alone, or set to null. Pick one, write it in the docs, and never make the client guess.
You should now be able to
- Define safe and idempotent precisely
- Choose between POST, PUT and PATCH on properties rather than habit
- Explain why a GET that mutates is dangerous
Loading…