Managing HTTP Headers
1. Using Content-Type Header
| Value | Use Case |
|---|---|
application/json | JSON request/response body |
application/xml | XML body |
application/x-www-form-urlencoded | HTML form submission |
multipart/form-data | File uploads |
application/octet-stream | Binary data |
application/merge-patch+json | JSON Merge Patch (RFC 7396) |
application/json-patch+json | JSON Patch (RFC 6902) |
text/event-stream | Server-Sent Events |
2. Using Accept Header
| Header | Meaning |
|---|---|
Accept: application/json | Client wants JSON |
Accept: application/json, application/xml;q=0.9 | Prefer JSON, fallback XML |
Accept: */* | Any type |
Accept: application/vnd.example.v2+json | Vendor-specific (versioning) |
3. Using Authorization Header
| Scheme | Format |
|---|---|
| Basic | Authorization: Basic base64(user:pass) |
| Bearer | Authorization: Bearer eyJhbGciOi... |
| API Key | Authorization: ApiKey abc123 or X-API-Key: abc123 |
| Digest | Authorization: Digest username="...", realm="...", ... |
| AWS Sig | Authorization: AWS4-HMAC-SHA256 ... |
4. Using Cache-Control Header
| Directive | Effect |
|---|---|
public | Cacheable by any cache (including CDN) |
private | Cacheable only by browser, not shared caches |
no-cache | Must revalidate with origin before serving |
no-store | Do not cache at all |
max-age=N | Fresh for N seconds |
s-maxage=N | Shared cache max age (overrides max-age for CDN) |
must-revalidate | Stale responses must revalidate |
immutable | Resource will never change |
stale-while-revalidate=N | Serve stale for N sec while refreshing |
5. Using ETag Header
| Type | Example | Comparison |
|---|---|---|
| Strong | ETag: "33a64df5" | Byte-for-byte identical |
| Weak | ETag: W/"33a64df5" | Semantically equivalent |
6. Using If-None-Match Header
| Request | Server Action |
|---|---|
If-None-Match: "abc" | If current ETag = "abc" → 304; else 200 + new body |
If-None-Match: * | POST/PUT only if resource doesn't exist (insert-only) |
7. Using If-Match Header
| Request | Server Action |
|---|---|
If-Match: "abc" | Apply mutation only if ETag matches; else 412 Precondition Failed |
Example: Optimistic Concurrency with If-Match
PUT /users/42 HTTP/1.1
If-Match: "v3-a1b2c3"
Content-Type: application/json
{"name": "Alice"}
# If current ETag is "v3-a1b2c3" → 200 OK
# Otherwise → 412 Precondition Failed
8. Using If-Modified-Since Header
| Request | Server Action |
|---|---|
If-Modified-Since: Sat, 29 Oct 2025 19:43:31 GMT | If unchanged since → 304; else 200 |
9. Using If-Unmodified-Since Header
| Request | Server Action |
|---|---|
If-Unmodified-Since: ... | Apply mutation only if not modified since; else 412 |
10. Using Location Header
| Status | Meaning |
|---|---|
| 201 Created | URI of newly created resource |
| 202 Accepted | URI to poll for operation status |
| 3xx Redirect | New URI to follow |
11. Using X-RateLimit Headers
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Total requests allowed in window |
X-RateLimit-Remaining | Requests left in current window |
X-RateLimit-Reset | Unix timestamp when window resets |
Retry-After | Seconds (or HTTP date) before retry allowed |
RateLimit-Policy NEW | RFC 9239 standardized policy |
12. Using CORS Headers
| Header | Purpose |
|---|---|
Access-Control-Allow-Origin | Allowed origin(s) or * |
Access-Control-Allow-Methods | Allowed HTTP methods |
Access-Control-Allow-Headers | Allowed request headers |
Access-Control-Allow-Credentials | true to send cookies |
Access-Control-Max-Age | Preflight cache duration (seconds) |
Access-Control-Expose-Headers | Headers JS can read |
13. Using Custom Headers
| Convention | Note |
|---|---|
X- prefix | Deprecated by RFC 6648 — use plain custom names |
X-Request-ID | Correlation/trace ID (de facto standard) |
X-Forwarded-For | Original client IP behind proxy |
X-Forwarded-Proto | Original protocol (http/https) |
Idempotency-Key | Client-generated key for safe retries |
X-API-Version | API version selector |