Card 04/ 10
GET vs POST
One reads and can be cached and repeated; the other asks the server to do something and may not be repeatable.
GET reads a resource and promises to change nothing, so it can be cached, bookmarked, prefetched and repeated freely. POST asks the server to process data and makes no such promise, so everything between client and server treats it with care. Choose between them by what the operation does, not by how much data it sends.
| Property | GET | POST |
|---|---|---|
| Changes data | No, it is safe | It may |
| Repeating it | Always safe | May repeat the action |
| Response cached | Yes, by default rules | Rarely, only when the server says so explicitly |
| Where the input goes | In the URL, as path and query | In the body |
| Bookmarked or shared as a link | Yes | No |
| Browser reload | Sends it again silently | Asks the user before resending |
| Appears in server and proxy logs | The whole URL, with its query | The URL only; the body is not logged by default |
Two consequences follow from that table.
Input in the URL is visible. A GET's parameters appear in browser history, logs and the Referer header of the next page. Never put a password, token or personal data in a query string, even for a read; send credentials in headers.
The choice is about intent. "Use POST for big requests" is the wrong rule. A form that registers a user is a POST whatever its size, because it creates something. A read with a large filter is still a read, and making it a POST loses the cache and the automatic retry. The QUERY method exists for exactly that case.
The rule for choosing. If the operation only reads and its input fits in a URL, use GET. If it creates, changes or triggers something, use POST, or PUT, PATCH or DELETE when one of those names the change more precisely.
← → move through sections and cards