Using HTTP request methods
Here is a quick guide to pick the right HTTP method and stay aligned with RFC 9110 semantics. Handy when you wonder “Should this be POST or PUT?”
Start with semantics
HTTP methods are signals of intent. Following RFC 9110 keeps caches, proxies, and browsers predictable.
Key terms
- safe: expected to have no state-changing effects on the server (GET/HEAD/OPTIONS/TRACE). Safe requests may be pre-fetched or repeated.
- idempotent: repeating the same request should not change the outcome (GET/HEAD/PUT/DELETE/OPTIONS/TRACE). This makes retries and retransmissions harmless.
- PATCH (RFC 5789, now in RFC 9110) is for partial updates. Whether it is idempotent depends on your implementation—combine with conditional requests (ETag + If-Match).
- Shared caches generally only store responses to safe methods. POST can be cached with explicit directives, but it is uncommon.
Method cheat sheet
Typical use, safety, and body handling at a glance (per RFC 9110).
Main methods
| Method | Typical use | Safety / idempotency | Body | Cache |
|---|---|---|---|---|
| GET | Fetch a resource. Default for links and assets. | safe / idempotent | Not sent in practice | Yes (via Cache-Control) |
| HEAD | Headers only, same as GET without a body. Good for health checks. | safe / idempotent | Not sent | Yes (same as GET) |
| POST | Create or trigger processing (forms, async APIs). | unsafe / not idempotent | Yes (Content-Type required) | Normally no (allowed if explicitly enabled) |
| PUT | Replace the target resource entirely. | unsafe / idempotent | Yes (complete new representation) | Generally no |
| PATCH | Partial update (diff or patch format). | unsafe / not idempotent by default | Yes (partial data) | Generally no |
| DELETE | Ask to delete a resource. | unsafe / idempotent by expectation | Rarely sent | No |
| OPTIONS | Discover capabilities; used by CORS preflight. | safe / idempotent | Allowed (often empty) | Possible but uncommon |
| TRACE | Reflect request for diagnostics. Often disabled. | safe / idempotent | Not sent | No |
Design notes
Choosing the method carefully keeps clients, caches, and intermediaries predictable.
Heuristics
- Keep GET free of side effects. Browsers may prefetch or crawl it anytime.
- POST is for “create or trigger.” Assume duplicates; use idempotency keys or replay protection if needed.
- PUT means “make this URL look exactly like the payload.” Send the full state and pair with If-Match to avoid lost updates.
- PATCH is for partial updates. If applying the patch twice would break things, enforce conditional requests (ETag/revision).
- DELETE should be idempotent: deleting twice should still succeed (200/204) rather than fail due to missing state.
- Use HEAD/OPTIONS for monitoring or capability checks. HEAD must mirror GET headers for caches to work.
Common pitfalls
Operational snags to watch for.
Checklist
- Do not mutate state on GET. Crawlers, previews, and prefetchers will call it.
- Avoid GET bodies. RFC 9110 allows them but defines no semantics; use query parameters instead.
- Always set Content-Type for POST/PUT/PATCH (application/json, application/problem+json, etc.) and declare UTF-8.
- Need idempotent POST? Support an Idempotency-Key header or similar server-side de-duplication.
- CORS preflight (OPTIONS) can be cached with Access-Control-Max-Age. Missing headers cause preflight on every request.
- TRACE is usually disabled to avoid cross-site tracing attacks; enable only with care.
Takeaway
Stick to RFC 9110 semantics for safety and idempotency. It keeps browsers, caches, and proxies predictable, and makes troubleshooting friendlier.