HTTP POST vs PUT: Differences and When to Use
Understand HTTP POST vs PUT differences: POST for server-assigned resource creation in collections (non-idempotent), PUT for client-specified URI creation/replacement (idempotent). REST API best practices, RFC guidance, and examples.
What is the difference between POST and PUT HTTP methods, and when should each be used for resource creation?
Background:
- According to RFC 2616, § 9.5, POST is used to create a new resource as a subordinate of the resource identified by the Request-URI
- According to RFC 2616, § 9.6, PUT is used to create or replace a resource at the specified URI
Question:
Which HTTP method should be used to create a resource, or should both be supported in a REST API design?
HTTP POST and PUT differ mainly in how they handle resource creation: POST lets the server assign the URI for new subordinate resources (non-idempotent), while PUT creates or fully replaces at a client-specified URI (idempotent). For creating resources, use POST on collections like /users when IDs are server-generated; opt for PUT if you know the exact path upfront, like /users/123. Smart REST APIs support both—POST for flexibility, PUT for precise updates—to match real-world needs without breaking idempotency rules.
Contents
- HTTP POST vs PUT: Core Differences
- RFC Guidance on POST and PUT Semantics
- Idempotence Explained
- When to Use HTTP POST for Creation
- When to Use HTTP PUT for Creation
- Should REST APIs Support Both?
- Real-World Examples and Response Codes
- Sources
- Conclusion
HTTP POST vs PUT: Core Differences
Ever wondered why your API calls sometimes duplicate resources on retry, but others don’t? That’s the POST vs PUT showdown in action. HTTP POST sends data to the server for processing—think form submissions or uploading files—where the server decides the outcome, often creating a new resource under a collection. It’s not safe to repeat blindly.
PUT, on the other hand, targets a specific URI. It either creates the resource there if missing or overwrites it entirely. No surprises on retries. According to the official PUT docs on MDN, “PUT is idempotent: calling it once is no different from calling it several times successively.”
This split makes sense for http post (over 9,000 monthly searches) versus http put scenarios. POST handles dynamic creation; PUT demands precision.
RFC Guidance on POST and PUT Semantics
Standards don’t leave much room for debate. RFC 2616 (still referenced widely) nails it: POST (§9.5) “creates a new resource as a subordinate of the resource identified by the Request-URI.” Picture posting to /api/orders—server spits back /api/orders/456.
PUT (§9.6)? “Used to create or replace a resource at the specified URI.” You PUT to /api/orders/456 directly. The MDN POST reference echoes this: “POST is used when the server determines the new resource’s URI.”
RestfulAPI.net breaks it down further: POST for adding kids to a collection; PUT for known spots. Conflicts? PUT might 409 if the spot’s taken. Clear rules keep APIs predictable.
But here’s the catch—modern HTTP/2 doesn’t rewrite these basics. They hold up.
Idempotence Explained
Idempotence sounds fancy, but it’s simple: repeat the request, get the same result. No extras.
HTTP PUT shines here. Hit /users/123 with the same payload ten times? Resource stays identical after the first. MDN confirms: “PUT … replaces a representation of the target resource with the request content.”
POST? Retry a /users POST, and boom—duplicate users. Not idempotent. That’s why http post put searches spike; devs wrestle with retry logic in distributed systems.
Why care? Networks flake. Load balancers retry. Idempotent methods like PUT prevent chaos. POST needs extra smarts, like checking If-Match headers.
When to Use HTTP POST for Creation
Go POST when the server owns the ID game. Classic case: user signup. Client hits POST /users with name and email. Server generates UUID, responds 201 Created and Location: /users/abc123.
Perfect for http post json or http post form—flexible bodies, server-side logic. MDN POST calls it standard for “data uploads, and actions that change server state.”
Collections scream POST: /posts, /comments. Client doesn’t guess IDs. Non-idempotent? Fine—POST signals “do this action.”
Drawback? Retries can multiply. Mitigate with idempotency keys (custom header, server tracks).
When to Use HTTP PUT for Creation
You know the URI? PUT it. Say a client imports data to /reports/2026-01-Q1. Doesn’t exist? PUT creates. Exists? Full replace.
MDN PUT spells success: 201 Created if new, or 200/204 if updated. Idempotent bliss.
Use for uploads where clients dictate paths, like static files or predefined slugs. Http put file fits perfectly.
But watch pitfalls. Client guesses wrong ID? Wrong resource. No partial updates—PUT is all-or-nothing. For patches, that’s PATCH’s job.
Should REST APIs Support Both?
Absolutely. Rigid “one method” rules ignore reality. Support POST for /resources (server IDs), PUT for /resources/{id} (client-known).
RestfulAPI.net advises: “POST for collection endpoints (/orders); PUT for individual (/orders/123).”
Hybrid wins: POST /users creates with server ID; PUT /users/me for self-updates. Clients choose. Docs explain conventions.
Trade-offs? More code. But flexibility trumps purity. GitHub, Stripe— they mix methods smartly.
Real-World Examples and Response Codes
Let’s code it.
POST creation:
POST /api/users HTTP/1.1
Content-Type: application/json
{"name": "Alice", "email": "alice@example.com"}
Server: 201 Created\nLocation: /api/users/123
PUT creation/replace:
PUT /api/users/123 HTTP/1.1
Content-Type: application/json
{"name": "Alice Updated", "email": "alice@new.com"}
New? 201 Created. Exists? 204 No Content.
Errors? POST might 400 Bad Request. PUT to taken spot: 409 Conflict.
Curl test: curl -X POST -d '{"key":"val"}' http://localhost:3000/items—watch http localhost post in action.
Sources
- PUT request method - HTTP | MDN
- POST request method - HTTP | MDN
- Difference between PUT and POST in REST API
- What is the difference between POST and PUT in HTTP? - Stack Overflow
Conclusion
HTTP POST rules new resources under collections with server-picked URIs—ideal for most creates. PUT handles known paths idempotently, perfect for replaces or upfront IDs. Back both in REST APIs for power and safety; let clients pick per context. Stick to MDN/RFC responses (201, 204), and your API stays robust. No one-size-fits-all—just smart design.