Just wondering, if the resource ID is known, I thought PUT is the recommended method? We usually use POST for creating a new resource for which you don't know an ID yet.
Just wondering, if the resource ID is known, I thought PUT is the recommended method? We usually use POST for creating a new resource for which you don't know an ID yet.
- POST: Perform resource-specific processing on the request content.
- PUT: Replace all current representations of the target resource with the request content.
I interpret this as the only immediate side-effect of PUT is supposed to be replacing the target resource with the request content. Everything else is POST, but that does not mean that we can't use POST for everything. Thus, JSON via PUT is not inherently odd at all. Calling a random API using PUT with JSON arguments that executes some code other than replacing a resource, would be odd.
I do think, though, that PUT may very well implicitly create a resource, if the name of that resource is the argument to the put. That is just something that's rather odd, as, often, the server has authority over the names of new resources.
I find PUT particularly helpful, as, given these constraints, I assume that PUT is idempotent; POST is not.
It's a (C)reate in CRUD, not an (U)pdate.
POST - Create, GET - Retrieve, PUT - Update, DELETE - Delete
CREATE /xxx
READ /zzz
UPDATE /yyy
DELETE /abcd
POST - Create, GET - Retrieve, PUT - Upsert, DELETE - Delete, PATCH - Update
Some APIs us PUT for creating items and let the clients specify the ID. If the IDs are UUIDs, the risk of creating duplicates is so slim that it's neglectable, and if that should happen, it's easy for the client to call again with a different ID. The real advantage of this approach is that if the API call times out, the client can just PUT again without having to fear creating a duplicate record. Recovering from a create with POST that has timed out can be pretty difficult because it can happen that the record was created just fine, but the internet connection died before the OK response reached the client.
The RFC 9110 (and also the old 2616) clearly state PUT is idempotent while POST isn't.
9.3.4 PUT
"The fundamental difference between the POST and PUT methods is highlighted by the different intent for the enclosed representation. The target resource in a POST request is intended to handle the enclosed representation according to the resource's own semantics, whereas the enclosed representation in a PUT request is defined as replacing the state of the target resource. Hence, the intent of PUT is idempotent and visible to intermediaries, even though the exact effect is only known by the origin server."
9.2.2 Idempotent Methods
"Idempotent methods are distinguished because the request can be repeated automatically if a communication failure occurs before the client is able to read the server's response. For example, if a client sends a PUT request and the underlying connection is closed before any response is received, then the client can establish a new connection and retry the idempotent request. It knows that repeating the request will have the same intended effect, even if the original request succeeded, though the response might differ."
Join us at Stytch (https://stytch.com/careers) if you have a strong opinion so you can decide whether this should be a POST or PUT :)
Recommended for what purpose?
The set of recommendations I'm familiar with is:
GET: requests without side effects
POST: requests with side effects
PUT: never use
other: never use
POST gets special treatment from browsers for various security risks. Otherwise, methods don't differ. You can use PUT as part of an effort to feel like you and your server have a secret code, but it's fundamentally the same thing as doing `GET /path/to/resource/put`.See the note here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GE...
https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-met...
Meanwhile, POST is generally not considered safe to repeat in case of failure, because the client/proxy does not know where exactly the failure happened and if thus the processing has been already done or not.
But if this is really your concern, you should also be using PUT to create new database records. In principle, those requests are safer to repeat than updates are, since the database will ignore repeated inserts and apply repeated updates. (Though as far as I can tell this only matters if your update adjusts a value rather than setting it outright.)
I don't get it. Isn't an idempotent effect still an effect?
> you should also be using PUT to create new database records.
If the client is free to define the identity, then I do. But if the resource gets e.g. an ID from Postgres sequence, then I need to use POST, because repeated call would create duplicates.