Method Properties — The RFC Definitions
HTTP methods are not just arbitrary verbs. RFC 7231 (obsoleted by RFC 9110 in 2022) defines three formal properties that methods can have. These properties determine how browsers, caches, proxies, and load balancers may treat a request without needing to understand the application semantics.
Safe Methods
A method is safe if it is essentially read-only — the client does not request or expect any state change on the server. The server *may* have side effects (logging, analytics) but these are not the client's concern.
Safe methods: GET, HEAD, OPTIONS, TRACE
Safety matters because:
- Browsers can prefetch safe requests without asking user permission
- Web crawlers can follow safe links automatically
- Users can bookmark and re-request safe URLs without concern
- Caches can serve safe responses without forwarding to the origin
Idempotent Methods
A method is idempotent if making the same request N times has the same effect as making it once. The responses may differ (the server might return a different timestamp each time), but the *state change* is identical.
Idempotent methods: GET, HEAD, OPTIONS, TRACE, PUT, DELETE
Note: all safe methods are also idempotent, but not all idempotent methods are safe. PUT and DELETE change state — they are just *predictably repeatable*.
Idempotency matters because:
- Load balancers can retry timed-out idempotent requests automatically
- Clients can safely retry on network failure without risk of duplication
- API clients can implement at-least-once delivery safely
Cacheable Methods
A method is cacheable if responses to it may be stored and reused for future equivalent requests, subject to cache-control directives.
Cacheable methods: GET, HEAD, POST (when explicitly marked cacheable)
The Properties Table
| Method | Safe | Idempotent | Cacheable |
|---|---|---|---|
| GET | Yes | Yes | Yes |
| HEAD | Yes | Yes | Yes |
| POST | No | **No** | Only if response includes explicit freshness |
| PUT | No | Yes | No |
| DELETE | No | Yes | No |
| PATCH | No | No | No |
| OPTIONS | Yes | Yes | No |
| TRACE | Yes | Yes | No |
| CONNECT | No | No | No |
GET and HEAD — Retrieval Semantics
GET — The Primary Retrieval Method
GET retrieves a representation of the target resource. The request must not include a message body (though RFC 9110 no longer prohibits it, all mainstream frameworks ignore GET bodies). All query parameters travel in the URL:
GET /api/users?page=2&limit=50&sort=created_at HTTP/1.1
Host: api.example.com
Accept: application/json
If-None-Match: "etag-abc123"
If-Modified-Since: Mon, 01 Jan 2024 00:00:00 GMT
Conditional GET: The If-None-Match and If-Modified-Since headers make a GET conditional. If the resource has not changed, the server returns 304 Not Modified with no body — saving bandwidth while validating freshness.
Partial GET: The Range header requests a byte range for resumable downloads and video streaming:
GET /video/large-file.mp4 HTTP/1.1
Range: bytes=1048576-2097151 ← request bytes 1MB–2MB
HTTP/1.1 206 Partial Content
Content-Range: bytes 1048576-2097151/15728640
Content-Length: 1048576
HEAD — Metadata Without Body
HEAD is identical to GET but the server must not send a response body. It is used to:
- Check if a resource exists without downloading it
- Get
Content-Lengthto pre-allocate a download buffer - Validate a cached response by checking
ETagorLast-Modified
# Check if a large file exists and get its size:
curl -I https://example.com/large-dataset.csv
# HTTP/1.1 200 OK
# Content-Length: 524288000
# Last-Modified: Fri, 10 Jan 2025 12:00:00 GMT
POST vs PUT vs PATCH
POST — Non-Idempotent Creation and Actions
POST submits data to the server. The server determines what to do with it — create a resource, process a command, or append to a collection:
POST /api/orders HTTP/1.1
Content-Type: application/json
{"product_id": 42, "quantity": 3}
HTTP/1.1 201 Created
Location: /api/orders/7891
POST is not idempotent. Sending the same POST twice creates two orders. This is correct behavior — a double-click should not double-charge a customer. Clients must implement idempotency keys if they need safe retry:
POST /api/orders HTTP/1.1
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
The server stores the key and returns the same response for duplicate requests with the same key — a pattern used by Stripe, PayPal, and most payment APIs.
PUT — Full Replacement
PUT replaces the target resource with the request body. The client supplies the complete new representation. If the resource does not exist, PUT creates it (returning 201); if it exists, PUT replaces it (returning 200 or 204):
PUT /api/users/42 HTTP/1.1
Content-Type: application/json
{"id": 42, "name": "Alice Smith", "email": "[email protected]", "role": "admin"}
HTTP/1.1 200 OK
PUT is idempotent — sending the same request twice leaves the resource in the same state. This makes PUT safe to retry on network timeout.
The PUT trap: PUT requires sending the *complete* resource representation. If you PUT only {"name": "Alice"} to a user resource, the server is supposed to replace the entire user with just a name — losing email, role, etc. Many APIs violate this and treat PUT as PATCH semantics. Use PATCH when you want partial updates.
PATCH — Partial Update
PATCH (RFC 5789, 2010) applies a partial modification to a resource. The request body is a patch document — a set of instructions describing the change:
PATCH /api/users/42 HTTP/1.1
Content-Type: application/merge-patch+json ← RFC 7396
{"name": "Alice Smith"} ← only update name, leave everything else
---
PATCH /api/documents/1 HTTP/1.1
Content-Type: application/json-patch+json ← RFC 6902
[{"op": "replace", "path": "/title", "value": "New Title"},
{"op": "add", "path": "/tags/-", "value": "python"}]
Two patch formats dominate:
- JSON Merge Patch (RFC 7396): Simple — send only the fields to change. Null values delete fields. Cannot append to arrays.
- JSON Patch (RFC 6902): Expressive — add, remove, replace, move, copy, test operations with JSON Pointer paths. Supports conditional patching.
PATCH is neither safe nor idempotent by the RFC definition (though idempotent PATCH implementations are possible and common). Clients should treat PATCH retries carefully.
DELETE and OPTIONS
DELETE — Resource Removal
DELETE requests removal of the target resource. A successful DELETE returns:
200 OKwith a body describing the deletion204 No Contentwith no body (most common)202 Acceptedif deletion is asynchronous
DELETE /api/users/42 HTTP/1.1
Authorization: Bearer eyJ...
HTTP/1.1 204 No Content
DELETE is idempotent: deleting an already-deleted resource should return 404 Not Found (or 204 — opinions vary), not an error that breaks retry logic.
OPTIONS — Capability Discovery and CORS Preflight
OPTIONS describes the communication options for the target resource. It is used in two contexts:
1. CORS Preflight — Before a cross-origin request with custom headers, the browser sends an OPTIONS preflight to check permissions:
OPTIONS /api/users HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
2. API Discovery — Servers may return an Allow header listing methods:
OPTIONS /api/users/42 HTTP/1.1
HTTP/1.1 200 OK
Allow: GET, PUT, PATCH, DELETE
Method Registration — IANA and WebDAV
The IANA Method Registry
HTTP methods are registered with IANA at https://www.iana.org/assignments/http-methods/. Anyone can register a new method by submitting an RFC or a specification. The registry prevents conflicts between separately developed protocol extensions.
WebDAV Methods
Web Distributed Authoring and Versioning (RFC 4918) added methods for filesystem-like operations over HTTP:
PROPFIND Retrieve properties of a resource (XML response)
PROPPATCH Change properties of a resource
MKCOL Create a collection (directory)
COPY Copy a resource to a new URL
MOVE Move a resource to a new URL
LOCK Lock a resource against concurrent modification
UNLOCK Release a lock
WebDAV powers macOS's Finder network folders and many CMS backends. It extends HTTP into a full filesystem protocol without changing the transport.
Custom Methods — Discouraged
RFC 9110 explicitly discourages defining custom HTTP methods. Instead:
- Use a standard method + differentiate by URL (
POST /actions/approve) - Use a request body field to specify the operation
- Use a custom header if semantics are truly unique
Custom methods break caches, proxies, and security tools that only understand the standard method vocabulary. The few legitimate custom methods (PATCH, SEARCH, REPORT from WebDAV) required years of standardization to gain broad support — that is the correct bar for a new method.