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.
So 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?)
You 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.
The client shouldn't know how to assemble URLs. The better way to do this is to POST to /Employees and have the server return the URL of the newly-created employee.
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.
Assuming the request is valid, PUT should work without regard to whether the resource existed already. You're asserting what should be there, and if it works, then it either creates it or overwrites what was there before.
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.
> 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.
Valid 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.
Not 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.
never 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.
Allocating 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...
Aside from my HTTP/REST rant, I think there's a much better discerning factor between POST and PUT. From the HTTP spec:
"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.
I am not sure about this, but I think that if you adhere to the HATEOAS principle you could provide URIs for non-existent resources that can then be used to PUT.
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.
In a RESTful API that I'm currently working on I did wonder about how best to create URIs for resources that you want to create via a PUT. To try to stick to the rule that "Servers must have the freedom to control their own namespace" (which is sensible if you are going to have multiple difference server implementations with different technology stacks) I chose to return a template URI for the container resource and then allow the client to use this template to create URIs. Along the lines of:
Actually you're quite right, yeah. My feeling though is that in cases like this it doesn't really matter what the PUT really does behind the scene. For your API consumer it just changes the user's picture (in some cases from None to one). So yeah, PUT can both create and update in this case, but the consumer has no need to make the distinction between the two semantics.
It seems to me that these discussions produce far more heat than light. If one needs to build an application, what is the benefit to sweating these details to such an extent? I don't mean to denigrate any of the fine work that's gone to figuring out these standards. But if the application and/or API works well, what difference does it make whether it uses post or put? I honestly would like to be enlightened. Is the motivation to make it so that people will know how api's work without reading about them, because they conform to a clear standard that everyone understands? If so, that hardly seems achievable. So I've honestly been long perplexed why people sweat this type of thing so hard.
My mobile client is consuming your API over a lossy and high latency network. Some of my requests will time out. Sometimes I will drop offline after sending a request and not be able to receive the response. Which requests can I retry safely?
For day to day coding, I don't think they're that important. But if you're building/extending/supporting a framework that hundreds or thousands of developers may use, it's good to have clarity on these issues.
Are there any examples of REST API implementations that are actually true to the original concepts or is everything kind of a "Web API" compromise? As a follow up, does, and should, anyone actually care really?
Comments like 'you are doing it wrong', and 'you haven't understood REST' are posted to most REST articles I have seen. Obviously nobody ever has done REST right.
I've been reading a lot of these articles and would like to think that I've implemented a RESTful API. I use GET for the get_all, get_one methods; PUT for create and PUT for replace/modify (as in replacing a field, not appending to it), HEAD for checking if certain resources exist, and DELETE for the obvious.
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.
Well I've created what I believe to be, and what this article describes twice now for internal web-services[1]. Its really quite easy if you are disciplined and it really ends up being a very nice interface. The trick becomes if you want to eat your own dogfood with a website. Since forms can only post and get it makes it tricky without JS.
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.
I suppose looking back I do have a concept of a session which is state. So no, but I organized my verbs and URL's to meet the specification and have the option to remove those sessions.
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.
You can however use XHR form submission[1] in the background (which is a good practice (better site responsiveness) after all) to use HTTP methods other than GET and POST.
I don't understand the distinction you're making between "trivially" and "non-trivially". Looking at pretty much any commercial CMS you can see that publishing documents can involve all kinds of business logic.
From you're massively oversimplified statement I can only conclude you don't understand REST. HTTP != REST. REST is how the architects of HTTP generally expected things to work, but due to tunneling, and other approaches to API design it, generally speaking, most systems that operate over HTTP don't actually work that way.
In fact I'd be willing to bet this comment form isn't all that RESTful.
The issue this piece exposes is much wider than REST and completely independent of the validity/desirability of REST. The semantics of PUT and POST are defined in the HTTP spec, a much lower level than the architectural one at which REST exists. As such, everyone developing HTTP-enabled code SHOULD (RFC 2119) obey the proper semantics to make sure we all use the same vocabulary. I mean, c'mon guys, there's only a handful of verbs!
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)
The biggest one is encoding state exclusively in the hypertext communication (what many people would call statelessness). Most web devs aren't comfortable doing away with sessions, but that's just fine as far as HTTP cares.
I really don't think SOAP is very ok with HTTP. It misuses the protocol and subverts its goals. For example, version 1 used POST for safe, idempotent requests.
I'm curious how security is typically handled in REST setups.
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.
Iron Money’s API[1] is RESTful and protected with OAuth 1.0a; since it uses the plaintext signature method, no nonce is used for each request.
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.
Yes, hence “RESTful.” The API is definitely not a prime example of a REST API since it doesn’t return the URIs of resources. It does, however, generally follow the other constraints.
Does anyone else think the naming of PUT/POST actually makes things more confusing? I feel like if they were better named at least a little confusion would be cleared up.
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.