ゆるテックノート

HTTP method anti-patterns

A quick list of “it works but it’s risky” behaviors. Avoid these to stay aligned with RFC 9110 and reduce surprises in production.

Frequent pitfalls

What goes wrong and how to fix it.

Patterns to avoid

Pattern Why it’s bad Fix
State changes on GET Prefetchers and link previews will trigger it; violates safety. Move side effects to POST/PUT/PATCH/DELETE; keep GET side-effect free.
POST for everything Caches/intermediaries cannot optimize; semantics are unclear. POST for create/trigger, PUT for replace, PATCH for partial, DELETE for removal.
Non-idempotent DELETE Second attempt fails (404/500), making retries risky. Return 204/200 even if already gone to keep DELETE idempotent.
PUT/PATCH without conditions Concurrent edits overwrite each other. Require If-Match for optimistic locking; return 412 on mismatch.
Bodies on GET Semantics undefined; intermediaries may drop them. Use query parameters or switch to POST/PUT/PATCH.
POST with sloppy status codes Only 200/500 makes clients guess; duplicates become errors. Use 201/204/409/412 appropriately and include Location/error details.
Blocking OPTIONS CORS preflight fails and actual requests never arrive. Allow OPTIONS and return correct Access-Control-Allow-* headers.

Warning signs

If you see these symptoms, revisit method usage.

Checklist

  • Only 200 and 500 are used in the API.
  • GET requests cause side effects when crawled externally.
  • Duplicate submissions create unintended duplicates.
  • Browsers show frequent CORS errors while server logs stay empty (OPTIONS blocked).
  • Specs lack statements on safety/idempotency per method.

Takeaway

HTTP methods come with safety and idempotency expectations. Avoiding these anti-patterns keeps retries, caching, and intermediaries predictable and RFC 9110-compliant.