I've just been reading about REST URLs and seen the following example:
/API/User/GetUser
Now if this is accessed over HTTP with a verb GET isn't this a bad URL becuase it describes the action (GET) in the URL?
It's more of a convention, than a hard rule, but I would rather see something like /API/User/7123. The GET/POST/etc describes the action verb, so also putting it in the url makes it redundant.
And in this situation there's no reason not to follow good proven practices.
Here's some good stuff: Understanding REST: Verbs, error codes, and authentication
There is no such thing as a REST URL. In fact, the word REST URL is pretty much an oxymoron. The Hypermedia As The Engine Of Application State Constraint guarantees that URLs are irrelevant: you are only ever following links presented to you by the server, anyway. You never see, read or type a URI anywhere. (Just like browsing the web: you don't look at the URL of a link, read it, memorize it and then type it into the address bar; you just click on it and don't care what it actually says.)
The term REST URL implies that you care about your URLs in your REST architecture. However, if you care about your URLs in your REST architecture, you are not RESTful. Therefore, REST URL is an oxymoron.
[Note: Proper URI design is very important for the URI-ness of a URI, especially the I part. Also, there's plenty of good usability reasons for pretty URLs. But both of these have nothing whatsoever to do with REST.]
Better way would be to have /API/User/7123 and use GET/POST method to signify operations
This is not necessarily bad... it has more to do with the framework you are using to generate your rest URLs. The link #Infinity posted is a good resource, but don't limit yourself to a set theory because it can cause an excessive amount of work in certain frameworks.
For example, there is no reason why you wouldn't want to run a GET on /API/Users/{id}/Delete to display an "are you sure" type of message before using the DELETE method.
/API/User/GetUser is not RESTful. Using a verb to identify a resource is not good thing. The example url is still valid but that doesn't make it right either. It is as wrong as the following declaration
String phoneNumber = "jhon#gmail.com";
Related
I need to define an end-point for an action the back-end is supposed to take: format the device.
The end-point I have come up with is:
POST /device/{deviceId}/format
without any body.
This, doesn't look RESTful though. Or is it?
Is there any alternative for this ? How can I make it RESTful?
REST doesn't care what spelling you use for your URI.
https://www.merriam-webster.com/dictionary/stop
https://www.merriam-webster.com/dictionary/go
https://www.merriam-webster.com/dictionary/procrastinate
All of these identifiers work fine. The machines don't care, because they aren't trying to extract semantic information from the identifier. General-purpose clients consider the URI to be opaque (aside from certain purely mechanical concerns permitted by RFC 3986).
This, doesn't look RESTful though. Or is it?
It can be fine, there might be better choices. Caching is a very important idea in REST, and if you expect that a successful POST request will change one of the representations that the client may have cached, then you will want to think about how to communicate to the client that some cache entries need to be invalidated.
Another way of expressing the same idea; you might imagine that our API is a collection of objects. What you are trying do here is send a format message to the device. A simple spelling of this might look like
Resource(/device/{deviceId}).FORMAT()
But our problem is that FORMAT isn't part of the uniform interface currently defined by HTTP; and trying to come up with semantics for FORMAT that are consistent across all resources isn't worth the bother.
What's are alternative? It's okay to use POST.
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”
Resource(/device/{deviceId}).POST()
and that works fine. Of course, sometimes we have more than one action that isn't worth standardizing. How do we discriminate between them?
Resource(/device/{deviceId}).POST(format)
The general purpose components route the request to your post handler, then your bespoke code interrogates the request and forward it to the module in your code that specializes in handling formatting requests.
In a RESTful Service, Resources that cannot all be retrieved at once are paginated. For example:
GET /foo?page=1
The question is, how should I handle a getAll request such as:
GET /foo
Taking discoverability/HATEOAS into consideration, I see a few options:
return a 405 Method Not Allowed and include a Link header to the first page:
Link=<http://localhost:8080/rest/foo?page=0>; rel=”first“
return a 400 Bad Request and include the Link header (same as above)
return a 303 See Other to the first paginated page
return a 200 OK but actually return only the first page (and include the URI of the next page into the Link):
Link=<http://localhost:8080/rest/foo?page=1>; rel=”next“
note: I would rather not do this, having learned not to manage anything for the client by default, if they haven't explicitly asked for it.
These are of course only a few options. I'm leaning towards the first, but I'm not sure if there is a best practice on this that I am not aware of.
Any feedback is appreciated.
Thanks.
Lets start with the fact that REST is not a set-in-stone protocol like SOAP, it's simply a means of structuring a service, similar to how languages are described as being Object-Oriented.
That all being said, I'd recommend the handling this as follows.
Treat a RESTful call like a function declaration.
GET /foo
foo()
Some functions require parameters.
GET /foo?start=??&count=??
foo(start, count)
Some languages support default parameters, others don't; you get to decide for yourself how you want to handle parameters.
With default parameters, you could assume that the function was defined as
foo(start = 0, count = 10)
so that a call to GET /foo would actually be equivalent to GET /foo?start=0&count=10, whereas a call to GET /foo?start=100 would be equivalent to GET /foo?start=100&count=10.
If you don't want default parameters, you could force the user of the API to explicitly set start and count:
foo(start, count)
so that a call to GET /foo would return a 400 Bad Request status code, but a call to GET /foo?start=0&count=10 would return a 200 OK status code along with the content contained by the specified range.
In either case you'll have to decide how you'll handle errors, such as
GET /foo?start=-10&count=99999999
If parameters have maximums and minimums, you'll need to decide whether to normalize the parameters, or simply return errors. The previous example might return a 400 Bad Request status code, but it could also be constrained to turn into:
GET /foo?start=0&count=1000
In the end it's up to you to decide what makes the most sense in the context of your application.
From a RESTful point of view, I think it perfectly alright to handle both representations the same. Consider a software with several versions you want to download, the latest one being 3.8. So if you want to get the latest version, you could address it with both GET /software/version/latest.zip and GET /software/version/3.8.zip until there comes a newer version. So two different links point to the same resource.
I like to imagine pagination pretty much the same. On the first page there are always the latest articles. So if no page-parameter is provided, you could simply imply it's 1.
The approach with the rel attribute goes in a slightly different direction. It's a creation of Google to better handle the problem with duplicate content and is primarily considered to be used in order to distinguish between a "main" page and pagination-pages. Here's how to use it:
//first page:
<link rel="next" href="http://www.foo.com/foo?page=2" />
//second page:
<link rel="prev" href="http://www.foo.com/foo?page=1" />
<link rel="next" href="http://www.foo.com/foo?page=3" />
//third and last page:
<link rel="prev" href="http://www.foo.com/foo?page=2" />
So from a SEO point of view it's a good idea (and recommended by Google) to use those elements. They also go perfectly with the resource-orientated idea of REST and the hypermedia representation of the resources.
Choosing one of your suggestions, I think the 303 See Other is the right way to go. It was intended to be used for this kind of purposes and is a good way to canonicalize your resources. You can make them available through many URIs, but have one "real" URI for a representation (like the software with different versions).
According to the specification, the response should look something like this:
303 See Other
Location: http:www.foo.com/foo?page=1
http:www.foo.com/foo?page=1
So you provide a Location-header with the "real" representation, and the body should contain a hypertext document linking to the new URI. Note that according to the specification the client is expected to send a GET request to the value of Location, but it doesn't have to.
//EDIT as answer to your comment (yep, it's really bad practice to claim something without proving it :-) - my bad!):
Google presented the rel="next" and rel="prev" attributes in September 2011 on the Official Webmaster Central Blog. They can be used additionally to (or in some cases instead of) the rel="canonical" tag.
Under those links you can find the differences between them explained:
rel="next" and rel="prev" link elements are "to indicate the relationship between component URLs in a paginated series"
the rel="canonical" "allows you to publicly specify your preferred version of a URL"
So there is a slight difference between them. So you can break down your problem to a canonical issue: There are several URLs pointing to the same resource (/foo and foo?page=1 but you have a preferred version of the URL (foo?page=1). So now there are a few options for a RESTful approach:
If there is no page-parameter given in the query, use a default value (e.g. 1) when processing it. I think in this specific case it is OK to use a default value even though you point it out as bad practice.
Respond with 303 See Other providing the preferred URL in the Location-header (as described above). I think a 3xx-response is the best (and most likely RESTfully intended) way to deal with duplicate/canonical content.
Respond with 400 Bad Request in case you want to force the client to provide a page-parameter (as explained by zzzzBov in his answer). Note that this response does not have something like a Location header (as assumed in your question), so the explanation why the request failed and/or the correct URL (if given) must go to the entity-body of the response. Also, note that according to the specification this response is commonly used when the client submits a bad/malformed representation (! not URL !) along with a PUT or POST request. So keep in mind that this also might be a little ambiguous for the client.
Personally, I don't think your suggestion to respond with 405 Method Not Allowed is a good idea. According to the specification, you must provide an Allow-header listing the allowed methods. But what methods could be allowed on this resource? I can only think of POST. But if you do not want the client to POST to it either, you could also respond with 403 Forbidden with an explanation why it is forbidden, or 404 Not Found if you do not want to tell why it is forbidden. So it might be a little ambiguous, too (in my opinion).
Using link-elements with the mentioned rel-attributes as you propose in your question is not essentially 'RESTful' because it's only hypermedia which is settled in the representation of the resource. But your problem (as far as I understand it) is that you want to decide how to respond to a specific request and which representation to serve. But still it's not absolutely pointless:
You can consider the whole SEO issue as a side effect of using rel="next/prev/canonical", but keep in mind that they also create connectedness (as the quality of having links) which is one of the characteristics of REST (see Roy Fielding's dissertation).
If you want to dive into RESTful Web Services (which is totally worth it) I recommend reading the book RESTful Web Services by Leonard Richardson and Sam Ruby.
In some cases not implicitly managing anything for the client can lead to a overlay complex interface, examples would be where the consumer isn't technical or isn't intending on building on top of interface, for example in a web page. In such cases even a 200 may be appropriate.
In other cases I would agree implicit management would be a bad idea as the where a consumer would want to be able to predict the response correctly and where a simple specification may be required. In such cases 405, 400 and 303.
It's a matter of context.
Does the HATEOAS (hypermedia as the engine of app state) recommendation imply that query strings are not RESTful?
Edit: It was suggested below that query strings may not have much to do with state and that therefore the question is puzzling. I would suggest that it doesn't make sense for the URI to have a query string unless the client were filling in arguments. If the client is filling arguments then it is adulterating the server-supplied URI and I wonder if this violates the RESTful principle.
Edit 2: I realize that the query string seems harmless if the client treats it as opaque (and the query string might be a legacy and therefore convenient). However, in one of the answers below Roy Fielding is quoted as saying that the URI should be taken to be transparent. If it is transparent then I believe adulterating is encouraged and that seems to dilute the HATEOAS principle. Is such dilution still consistent with HATEOAS? This raises the question of whether REST is calling for the tight coupling that URI building seems to be.
Update At this REST tutorial http://rest.elkstein.org/ it is suggested that URI building is bad design and is not RESTful. It also iterates what was said by #zoul in the accepted answer.
For example, a "product list" request could return an ID per product, and the specification says that you should use http://www.acme.com/product/PRODUCT_ID to get additional details. That's bad design. Rather, the response should include the actual URL with each item: http://www.acme.com/product/001263, etc. Yes, this means that the output is larger. But it also means that you can easily direct clients to new URLs as needed
If a human is looking at this list and does not want what he/she can see, there might be a "previous 10 items" and a "next 10 items" button, however, if there is no human, but rather a client program, this aspect of REST seems a little weird because of all the "http://www" that the client program may have no use for.
In Roy Fielding's own words (4th bullet point in the article):
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs, such as is done in HTML forms and URI templates, by defining those instructions within media types and link relations.
In other words, as long as the clients don't get the pieces they need to generate URIs in out-of-band information, HATEAOS is not violated.
Note that URI templates can be used in URIs without query strings as well:
http://example.com/dictionary/{term}
So the question is more about whether it is RESTful to allow the client to construct URLs than whether it is RESTful to use query strings.
Notice how the amount of information served to the client in the example above is exactly equivalent to serving an exhaustive list of all the possible terms, but is a lot more efficient from a bandwidth point of view.
It also allows the client to search the dictionary while respecting HATEAOS, which would be impossible without the in-band instructions. I am quite confident that Roy Fielding is not promoting a Web without any search feature...
About your third comment, I think Roy Fielding is encouraging API designers to have "transparent" URIs as an extra feature on top of HATEAOS. I don't interpret his quote in zoul's answer as a statement that clients would use "common sense" to navigate an API with clear URIs. They would still use in-band instructions (like forms and URI templates). But this does not mean that transparent URIs are not way better than dark, surprising, opaque URIs.
In fact, transparent URIs provide added value to an API (debugging is one use case I can think of where having transparent URIs is invaluable).
For more info about URI templates, you can have a look at RFC6570.
My take on it is that REST itself says nothing about whether URI are opaque or transparent but that REST app should not depend on the client to construct URI that the server hasn't already told it about. There are a variety of ways for the server to do this: for example, a collection which may include links to its members, or an HTML form with the GET method will obviously cause a URI with params to be created client-side and fetched, or there are at least a couple of proposed standards for URI templates. The important thing for REST is that the description of valid URI should be defined somehow by the server in the responses it gives to clients, and not in some out-of-band API documentation
URI transparency is a good thing in the same way as transparency anywhere is a good thing - it promotes and permits novel and unplanned uses for resources beyond what the designer had originally imagined - but (at least in my understanding) nice URIs are not required to describe an interface as RESTful
I would suggest that it doesn't make
sense for the URI to have a query
string unless the client were filling
in arguments.
That does not seem true to me. If you ask server for a handful of photos, it’s perfectly valid for the server to return something like this:
<photos>
<photo url="http://somewhere/photo?id=1"/>
<photo url="http://somewhere/photo?id=2"/>
</photos>
You could use /photo/id/xx path instead, but that’s not the point. These URLs are usable even without the client changing them. As for your second point:
If the client is filling arguments
then it is adulterating the
server-supplied URI and I wonder if
this violates the RESTful principle.
I guess this is the heart of your question. And I don’t think you have to treat URLs as opaque identifiers, see this quote by Roy Fielding himself:
REST does not require that a URI be
opaque. The only place where the word
opaque occurs in my dissertation is
where I complain about the opaqueness
of cookies. In fact, RESTful
applications are, at all times,
encouraged to use human-meaningful,
hierarchical identifiers in order to
maximize the serendipitous use of the
information beyond what is anticipated
by the original application.
I don’t see what query strings have to do with state tracking. The point of the HATEOAS principle is to refrain from tracking the state on the client, from “cheating” and going to “known” URLs for data. Whether those URLs have query strings or not seems irrelevant to me.
Oh. Maybe you’re interested in something like search URLs where a certain part of the URL has to change according to search criteria? Because such URLs would seemingly have to be known beforehand, thus representing the out-of-band information that we seek to eliminate with REST? I think that this can be solved using URL templates. Example:
client -> server
GET /items
server -> client
/* …whatever, an item index… */
<search by="color">http://somewhere/items/colored/{#color_id}</search>
This way you don’t need no a priori URL knowledge to search and you should be true to the hypermedia state tracking principle. But my grasp of REST is very weak, I’m answering mainly to sort things in my head and to get feedback. Surely there’s a better answer.
No HATEOAS does not mean query strings are not RESTful. In fact the exact opposite can be the case.
Consider the common login scenario where the user tries to access a secured resource and they are sent to a login screen. The URL to the login screen often contains a query string parameter named redirectUrl, which tells the login screen where to return to after a successful login. This is an example of using URIs to maintain client state.
Here is another example of storing client state in the URL: http://yuml.me/diagram/scruffy/class/[Company]<>-1>[Location], [Location]+->[Point]
To follow-on from what Darrel has said, you do not need to alter the URL to include a second URL.
For cookie-based authentication you could return the login form within the body of the 401 response, with an empty form action, and use unique field names that can be POSTed to and processed by every resource. That way you avoid the need for a redirect entirely. If you can't have every resource process log-in requests, you can make the 401 form action point to a log-in action resource and put the redirect URL in a hidden field. Either way, you avoid having an ugly URL-in-a-URL, and the first way avoids the need for both an RPC log-in action and a redirect, keeping all the interaction focused on the resource.
I learned the term "RESTful" as a Rails developer. After reading wikipedia, also here and here.
I don't get it. It seems to me, Rails is only using a concise way to describe URLs. It seems to me every URI is RESTful, in it's designed scope.
For example, I think GET /delete?student_id=3 is RESTful in the scope the the application itself.
Can anybody tell me which constrict does it violate? Please refer the constrict from the REST definition.
A GET request should be idempotent and the request should not leave any side-effects on the server. Quoting from the HTTP spec sec 9.1.1:
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.
Therefore GET /delete?student_id=3 already violates the idempotency assumption of the GET verb, since it will delete a record on the server.
A RESTful interface is a uniform interface, which in other words means that a GET is supposed to behave as required by the HTTP spec. And this is what the spec says:
The GET method means retrieve whatever information (in the form of an
entity) is identified by the Request-URI. If the Request-URI refers
to a data-producing process, it is the produced data which shall be
returned as the entity in the response and not the source text of the
process, unless that text happens to be the output of the process.
...
It seems to me, Rails is only using a
concise way to describe URLs. It seems
to me every URI is RESTful, in it's
designed scope.
URIs are neither RESTful or non-RESTful. REST is an architectural style for which you need to consider the overall application.
GET is the method for the retrieval request. If you want to put this in the context of the REST dissertation, if your GET request has side-effects, it will then break a few other constraints, for example regarding the cache.
You could also potentially design a RESTful system where a GET /delete?student_id=3 request gives you a representation telling you (or asking you to confirm) that you want to delete that student, so long as it doesn't actually perform the delete operation.
A GET should be safe to be RESTful, but obviously combined with a delete it is unsafe.
So it looks RESTful but doesn't act RESTful. So it fails the duck test.
See Section 5.1.5. Your example violates the uniform interface constraint. It does this by violating the HTTP spec.
Apparently, REST is just a set of conventions about how to use HTTP. I wonder which advantage these conventions provide. Does anyone know?
I don't think you will get a good answer to this, partly because nobody really agrees on what REST is. The wikipedia page is heavy on buzzwords and light on explanation. The discussion page is worth a skim just to see how much people disagree on this. As far as I can tell however, REST means this:
Instead of having randomly named setter and getter URLs and using GET for all the getters and POST for all the setters, we try to have the URLs identify resources, and then use the HTTP actions GET, POST, PUT and DELETE to do stuff to them. So instead of
GET /get_article?id=1
POST /delete_article id=1
You would do
GET /articles/1/
DELETE /articles/1/
And then POST and PUT correspond to "create" and "update" operations (but nobody agrees which way round).
I think the caching arguments are wrong, because query strings are generally cached, and besides you don't really need to use them. For example django makes something like this very easy, and I wouldn't say it was REST:
GET /get_article/1/
POST /delete_article/ id=1
Or even just include the verb in the URL:
GET /read/article/1/
POST /delete/article/1/
POST /update/article/1/
POST /create/article/
In that case GET means something without side-effects, and POST means something that changes data on the server. I think this is perhaps a bit clearer and easier, especially as you can avoid the whole PUT-vs-POST thing. Plus you can add more verbs if you want to, so you aren't artificially bound to what HTTP offers. For example:
POST /hide/article/1/
POST /show/article/1/
(Or whatever, it's hard to think of examples until they happen!)
So in conclusion, there are only two advantages I can see:
Your web API may be cleaner and easier to understand / discover.
When synchronising data with a website, it is probably easier to use REST because you can just say synchronize("/articles/1/") or whatever. This depends heavily on your code.
However I think there are some pretty big disadvantages:
Not all actions easily map to CRUD (create, read/retrieve, update, delete). You may not even be dealing with object type resources.
It's extra effort for dubious benefits.
Confusion as to which way round PUT and POST are. In English they mean similar things ("I'm going to put/post a notice on the wall.").
So in conclusion I would say: unless you really want to go to the extra effort, or if your service maps really well to CRUD operations, save REST for the second version of your API.
I just came across another problem with REST: It's not easy to do more than one thing in one request or specify which parts of a compound object you want to get. This is especially important on mobile where round-trip-time can be significant and connections are unreliable. For example, suppose you are getting posts on a facebook timeline. The "pure" REST way would be something like
GET /timeline_posts // Returns a list of post IDs.
GET /timeline_posts/1/ // Returns a list of message IDs in the post.
GET /timeline_posts/2/
GET /timeline_posts/3/
GET /message/10/
GET /message/11/
....
Which is kind of ridiculous. Facebook's API is pretty great IMO, so let's see what they do:
By default, most object properties are returned when you make a query.
You can choose the fields (or connections) you want returned with the
"fields" query parameter. For example, this URL will only return the
id, name, and picture of Ben:
https://graph.facebook.com/bgolub?fields=id,name,picture
I have no idea how you'd do something like that with REST, and if you did whether it would still count as REST. I would certainly ignore anyone who tries to tell you that you shouldn't do that though (especially if the reason is "because it isn't REST")!
Simply put, REST means using HTTP the way it's meant to be.
Have a look at Roy Fielding's dissertation about REST. I think that every person that is doing web development should read it.
As a note, Roy Fielding is one of the key drivers behind the HTTP protocol, as well.
To name some of the advandages:
Simple.
You can make good use of HTTP cache and proxy server to help you handle high load.
It helps you organize even a very complex application into simple resources.
It makes it easy for new clients to use your application, even if you haven't designed it specifically for them (probably, because they weren't around when you created your app).
Simply put: NONE.
Feel free to downvote, but I still think there are no real benefits over non-REST HTTP. All current answers are invalid. Arguments from the currently most voted answer:
Simple.
You can make good use of HTTP cache and proxy server to help you handle high load.
It helps you organize even a very complex application into simple resources.
It makes it easy for new clients to use your application, even if you haven't designed it specifically for them (probably, because they weren't around when you created your app).
1. Simple
With REST you need additional communication layer for your server-side and client-side scripts => it's actually more complicated than use of non-REST HTTP.
2. Caching
Caching can be controlled by HTTP headers sent by server. REST does not add any features missing in non-REST.
3. Organization
REST does not help you organize things. It forces you to use API supported by server-side library you are using. You can organize your application the same way (or better) when you are using non-REST approach. E.g. see Model-View-Controller or MVC routing.
4. Easy to use/implement
Not true at all. It all depends on how well you organize and document your application. REST will not magically make your application better.
IMHO the biggest advantage that REST enables is that of reducing client/server coupling. It is much easier to evolve a REST interface over time without breaking existing clients.
Discoverability
Each resource has references to other resources, either in hierarchy or links, so it's easy to browse around. This is an advantage to the human developing the client, saving he/she from constantly consulting the docs, and offering suggestions. It also means the server can change resource names unilaterally (as long as the client software doesn't hardcode the URLs).
Compatibility with other tools
You can CURL your way into any part of the API or use the web browser to navigate resources. Makes debugging and testing integration much easier.
Standardized Verb Names
Allows you to specify actions without having to hunt the correct wording. Imagine if OOP getters and setters weren't standardized, and some people used retrieve and define instead. You would have to memorize the correct verb for each individual access point. Knowing there's only a handful of verbs available counters that problem.
Standardized Status
If you GET a resource that doesn't exist, you can be sure to get a 404 error in a RESTful API. Contrast it with a non-RESTful API, which may return {error: "Not found"} wrapped in God knows how many layers. If you need the extra space to write a message to the developer on the other side, you can always use the body of the response.
Example
Imagine two APIs with the same functionality, one following REST and the other not. Now imagine the following clients for those APIs:
RESTful:
GET /products/1052/reviews
POST /products/1052/reviews "5 stars"
DELETE /products/1052/reviews/10
GET /products/1052/reviews/10
HTTP:
GET /reviews?product_id=1052
POST /post_review?product_id=1052 "5 stars"
POST /remove_review?product_id=1052&review_id=10
GET /reviews?product_id=1052&review=10
Now think of the following questions:
If the first call of each client worked, how sure can you be the rest will work too?
There was a major update to the API that may or may not have changed those access points. How much of the docs will you have to re-read?
Can you predict the return of the last query?
You have to edit the review posted (before deleting it). Can you do so without checking the docs?
I recommend taking a look at Ryan Tomayko's How I Explained REST to My Wife
Third party edit
Excerpt from the waybackmaschine link:
How about an example. You’re a teacher and want to manage students:
what classes they’re in,
what grades they’re getting,
emergency contacts,
information about the books you teach out of, etc.
If the systems are web-based, then there’s probably a URL for each of the nouns involved here: student, teacher, class, book, room, etc. ... If there were a machine readable representation for each URL, then it would be trivial to latch new tools onto the system because all of that information would be consumable in a standard way. ... you could build a country-wide system that was able to talk to each of the individual school systems to collect testing scores.
Each of the systems would get information from each other using a simple HTTP GET. If one system needs to add something to another system, it would use an HTTP POST. If a system wants to update something in another system, it uses an HTTP PUT. The only thing left to figure out is what the data should look like.
I would suggest everybody, who is looking for an answer to this question, go through this "slideshow".
I couldn't understand what REST is and why it is so cool, its pros and cons, differences from SOAP - but this slideshow was so brilliant and easy to understand, so it is much more clear to me now, than before.
Caching.
There are other more in depth benefits of REST which revolve around evolve-ability via loose coupling and hypertext, but caching mechanisms are the main reason you should care about RESTful HTTP.
It's written down in the Fielding dissertation. But if you don't want to read a lot:
increased scalability (due to stateless, cache and layered system constraints)
decoupled client and server (due to stateless and uniform interface constraints)
reusable clients (client can use general REST browsers and RDF semantics to decide which link to follow and how to display the results)
non breaking clients (clients break only by application specific semantics changes, because they use the semantics instead of some API specific knowledge)
Give every “resource” an ID
Link things together
Use standard methods
Resources with multiple representations
Communicate statelessly
It is possible to do everything just with POST and GET? Yes, is it the best approach? No, why? because we have standards methods. If you think again, it would be possible to do everything using just GET.. so why should we even bother do use POST? Because of the standards!
For example, today thinking about a MVC model, you can limit your application to respond just to specific kinds of verbs like POST, GET, PUT and DELETE. Even if under the hood everything is emulated to POST and GET, don't make sense to have different verbs for different actions?
Discovery is far easier in REST. We have WADL documents (similar to WSDL in traditional webservices) that will help you to advertise your service to the world. You can use UDDI discoveries as well. With traditional HTTP POST and GET people may not know your message request and response schemas to call you.
One advantage is that, we can non-sequentially process XML documents and unmarshal XML data from different sources like InputStream object, a URL, a DOM node...
#Timmmm, about your edit :
GET /timeline_posts // could return the N first posts, with links to fetch the next/previous N posts
This would dramatically reduce the number of calls
And nothing prevents you from designing a server that accepts HTTP parameters to denote the field values your clients may want...
But this is a detail.
Much more important is the fact that you did not mention huge advantages of the REST architectural style (much better scalability, due to server statelessness; much better availability, due to server statelessness also; much better use of the standard services, such as caching for instance, when using a REST architectural style; much lower coupling between client and server, due to the use of a uniform interface; etc. etc.)
As for your remark
"Not all actions easily map to CRUD (create, read/retrieve, update,
delete)."
: an RDBMS uses a CRUD approach, too (SELECT/INSERT/DELETE/UPDATE), and there is always a way to represent and act upon a data model.
Regarding your sentence
"You may not even be dealing with object type resources"
: a RESTful design is, by essence, a simple design - but this does NOT mean that designing it is simple. Do you see the difference ? You'll have to think a lot about the concepts your application will represent and handle, what must be done by it, if you prefer, in order to represent this by means of resources. But if you do so, you will end up with a more simple and efficient design.
Query-strings can be ignored by search engines.