6 ms·
First of all, this piece was written in 2008. The tl;dr is that GET/DELETE/PUT are idempotent, whereas POST is not. The author suggests that POST should be use
by kgtm 15y ago
First of all, this piece was written in 2008.
The tl;dr is that GET/DELETE/PUT are idempotent, whereas POST is not. The author suggests that POST should be used on "collection-like" resources, e.g. '/Persons' to create a new Person while PUT to update/create a specific Person (i.e. you know the identifier of the Person in the system). Multiple PUTs on that resource, with the same payload body, will not change the state of system.
This makes sense, and, as far as I have seen, is the "normal" way to approach REST (for various definitions of REST). What puzzles me is that the first referenced article ("How to Create a REST Protocol") actually doesn't advocate the PUT=CREATE mapping. Maybe I am missing something?
Reaching the article's concluding paragraph, the author states: "PUT must create or update a specified resource by sending the full content of that same resource". OK, but this complicates matters, since the client now needs to know how to address a particular resource i.e. have implementation/domain-specific knowledge.
My approach is using POST to create, and PUT to update (NOT create/update). I find that it simplifies things quite a bit.
- tjpick 15y ago> since the client now needs to know how to address a particular resource for creates, it's still possible that the client has previously queried the server and been allocated an appropriate address that the new resource should be PUT to (eg been advised of the next free auto-id, or creating using client generated GUIDs). PUT seems appropriate in these cases.
- kgtm 15y agoValid point, and PUT would indeed be appropriate. But are there any benefits to this approach? I'm sure there is an edge case I can't think of right now; as I see it, there is one more trip to the server, plus extra code to accommodate it versus a simple POST to a collection endpoint.
- icebraining 15y agoNot all resources are part of a collection, though. It can be a resource linked from another. Let's say 'product' resource you're selling. That may return a bunch of data, including a link to a 'description' resource about the product. Since you've never created such description, the link will return 404, but you can PUT a description to that URL without having any extra trips, just the visit to the product.
- tjpick 15y agonever had the call to do it myself. Just something I keep in the back of my mind for a rainy day. The benefits would be application specific, I don't think it's something that you balance against POST to the collection in the general case and do one approach exclusively. I have used POST to collection extensively and PUT for create never. One example I can think of is you are making one of those sign up forms that does AJAX to check that the username is free or not. You could use a PUT in a case like that because you've already done the extra server trip as part of a usability improvement.
- justincormack 15y agoAllocating an address sounds much like creating a stub entry resource. You could argue that you should use a POST for that, and then PUT to it. You cannot query for say next free id with GET as it has the wrong semantics, and might get cached...
- peterwwillis 15y agoSo let's say there's a resource that you want to update, but you don't know if it exists or not. Either you can GET (or HEAD or something) to see if it exists and then PUT if it exists or POST if it doesn't exist yet. Or you can just have PUT create and/or update it whether or not it exists, skipping the requirement of knowing whether you need to create it or not. (Or did I miss something?)
- kgtm 15y agoYou are one step ahead though. How can you address a resource if you don't know beforehand the representation of its identifier? Say, you want to create a new Employee under /Employees. Do you just issue a 'GET /Employees/1234' and assume '1234' is a valid identifier when you get a 404? What if the system expects a MongoDB _id such as '47cc67093475061e3d95369d'? A workaround, as was suggested by an other poster, is that the client interrogates the system for a valid identifier and then proceeds. This especially makes sense when, as noted, you are dealing with resources that belong to no collection.
- ww520 15y agoAll these are good points. However, in the case where the Id is the nature key (e.g. SSN), the Id can be known from the user input. Creating an employee is just a matter of PUT his full record along with his SSN as the Id.
- itcmcgrath 15y agoSave yourself some hassle. Don't key on SSN. 1) Encryption (and then indexing) becomes harder. 2) SSN's can change, for many reasons. (eg: http://consumerist.com/2008/11/can-i-change-my-social-security-number.html http://consumerist.com/2008/11/can-i-change-my-social-securi..., data entry error, etc)
- ericHosick 15y agoIt is a bad idea to use anything entered by a user as the primary key. It is ok to use data entered by users to assure the uniqueness of a record (unique indexes/constraints).