PUT or POST: The REST of the Story
jcalcote.wordpress.com
jcalcote.wordpress.com
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.
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.
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.
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.
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.
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-securi..., data entry error, etc)
It is ok to use data entered by users to assure the uniqueness of a record (unique indexes/constraints).
You have to use PUT to enable creating something only when the server URL that the resource will be available at is not known to the client.
And I assume you mean POST for paragraph 2?
I did mean "POST" in paragraph 2, yes. Thanks. :)
"The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. [...] In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource. If the server desires that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request."
So if you want to create the user Foo and you somehow know about the URI example.com/users/Foo, then you can directly PUT your information to that URI. This URI points directly to the enclosed entity, the user. If you only know the URI of the enclosing resource (aka collection), then you MUST do a POST to example.com/users/.
So that's the semantics of it, PUT deals directly with the resource that the URI points to, while POST deals with a collection of subordinate resources.
However, the REST catch is that if you follow the HATEOAS principle, there's (almost+) no way you would know about example.com/users/Foo. In the REST world, you would (almost) never use PUT for creating, because if that resource doesn't already exist, you would (almost) never get a URI to it by traversing the hypertext representation of the application state.
+ I say almost because you could have something like a GET example.com/users?name=Foo that would return 404 with the URL where to PUT to create this user. Not sure how HATEOAS proposes you get to a URL like example.com/users?name=Foo though, perhaps someone more knowledgeable can pitch in.
Example a user profile may contain a URI to the user's profile picture although that does not exist yet, which means that you could grab that URI and then PUT a picture there.
or
http://foo/floop.ashx?path=/bar/{name}
The client replacing {name} with the actual intended resource name.
Not sure if this is a good idea or not - but it seems to work!
Is REST really just a pipe-dream in practice?
(Downvotes, ho!)
Otherwise I've been very happy and content with my 100%[1] restful webservices.
[1] According to this article, the one it linked to, and a medium skimming of the original dissertation.
But I guess since I'm using a cookie-based sessions its less of an issue for state changes since the state stays mostly on the client.
[1] e.g. http://jquery.malsup.com/form/#json
if you used a browser to write that comment, I would say rest is working pretty well.
In fact I'd be willing to bet this comment form isn't all that RESTful.
I'm more interested if anyone has managed to use REST for an API that has more business logic than simply publishing documents.
The framework I'm using assigns any visit a new session, but it's unused in the sense that the REST interaction doesn't require the session and also doesn't use it - authentication is handled using a the "Authorization: basic" header.
This is HTTP not REST. You need to understand this even if you're against REST.
(edited to remove tl;dr. It looked much longer in my text box)
If REST is the architecture that HTTP is an protocol for can you really use HTTP properly without understanding REST?
Those would be rather RESTless.
Wouldn't you want to have some nonce anyway on requests that modify resources (and thus allowing idempotency even if you POST everything) ?
Or are resources typically protected purely by some non-HTTP auth process, i.e. a custom header, or username/password/API key provided as POST data?
If sending data to a resource is protected via simple basic authentication then you can use a auto-posting form to send it on behalf of a user, if they previously entered this data for testing in their browser. I.e. basic cross-site request forgery.
I’m not quite sure what your security question is. Since the API and web app use different authentication schemes and have different endpoints, there is no risk of CSRF.