Hacker News new | past | comments | ask | show | jobs | submit login

The REST version makes it clear that you are dealing with operations on a resource. The URL identifies a thing in a consistent way, while the method and corresponding data allow you to manipulate it.

The biggest benefit comes when building a cache architecture. RESTful API's (when properly implemented) come with built-in assumptions about idempotency. You end up in a place where you can easily cache GET requests while reasoning in a very consistent way about where changes to a resource will be made.

It's a pattern that comes with a lot of really useful benefits.

Now all of those same qualities can be built into other architectural styles (such as the one you propose). However, I find that it becomes much harder to reason about the role of operations and what they're actually doing when you lose that clear distinction that REST enforces.

I do want to quibble with one thing as well:

In REST the parameters are spread over 3 places, the action, the url and the post parameters themselves

That's true for any modular system isn't it? You have the object you are operating on, you have the operation, and you have the data. Object-oriented systems and even most structured languages (like Javascript for instance) make this distinction at some level. Why is that not appropriate for web architecture?




Just because something is GET doesn't mean it can be cached. It's not consistent, and every API call needs to be evaluated individually. The thing with REST is that it treats all functions as a variant of a CRUD operation, while functions may do more than just CRUD or a combination of CRUD operations in a single API call. Imagine if all your javascript functions had to be prefixed with GET/UPDATE/DELETE/etc.. you would feel constricted, and for what reason? Imagine if your function names had data in the call path MyCourse.32423.Delete(); that doesn't look very good does it? 32423 would look alot better inside Delete().


GET requests, by definition, should have no side-effects. Which makes them cacheable. Many browsers cache GET requests by default unless cache-control tells them not to.

You can most definitely write a GET request that contains side-effects, but that's because you're doing it wrong (tm).

Imagine if your function names had data in the call path MyCourse.32423.Delete(); that doesn't look very good does it? 32423 would look alot better inside Delete().

That's not data, that's an object. "MyCourse.32423" is the actual resource. It would actually look something more like:

MyCourse32423.Delete();

Which seems pretty reasonable to me if we're trying to map this into programming language semantics (which I'm not even sure we should be doing).


I cringe a little bit whenever someone tries to present caching as simple or straightforward.


I don't see that anywhere in the post. All I saw was "GET"s shouldn't modify state and should be cacheable. That seems perfectly in line with the spec.


The only problem I have with your comment is that REST is not specified, it's a style:

http://en.wikipedia.org/wiki/Representational_state_transfer


GET being cacheable/idempotent is part of the HTTP spec, and has nothing to do with REST: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13...


I meant the HTTP spec which is where GETs specified.


>It's a pattern that comes with a lot of really useful benefits.

Sure, but people can implement that pattern without buying into the whole clumsy REST edifice.

For example, a strict reading of REST (and RESTers support such readings!) would tell me that if I have an API that takes two cities and returns the distance between them, then I must expose a URI pointing to every combination of cities.

See here: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte...

>>A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) ... From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations. ... [Failure here implies that out-of-band information is driving interaction instead of hypertext.] [emphasis mine]

So, 1000 cities, you must send a million links over the network rather than 1000 possible parameters plus the formatting.

Now, some RESTers assure me that, no, you can somehow communicate to the user that [prefix] / [first city] / [second city] will get you that answer; that a server can "instruct clients on how to construct appropriate URIs".

Fine, but then we're right back to custom, author-documented APIs and RPCs: "to do that, format the call this way". Right back where we were before trying to force-fit everything into a CRUD mold with increasingly bizarre tables just to make all the calls work.

Or maybe a REST purist would tell me that I'm supposed to link a URI for the starting city: [root]/distances/[start city]/, and then from there link them to possible choices of the second city: [root]/distances/[start city]/[end city]/ .

Fine, but why jump through two pointless hoops, when I know what I want, and I prefer to just send one request rather than pointlessly spend bandwidth navigating a path I don't care for?


> 1. [send a link for each possible combination]

> 2. instruct clients on how to construct appropriate URIs

> 3. link a URI for the starting city and then from there link them to possible choices of the second city

All three of these are possible RESTful solutions, and I can imagine situations where each of them might make sense.

But what you're probably looking for is something like this:

  <form><select name="city1">...</select><select name="city2">...</select></form>
(Using URL templates is a potentially simpler way to achieve the same thing). This is, of course, your solution 2.

There are tradeoffs involved in using this style. Are they worth it? That really depends on the larger system and all kinds of details which you've left out.


That is not a RESTful solution, though: what resource is it acting on? What are the four CRUD operations for it?

You have to come up with some added, unnecessary, implementation-exposing abstraction like "CityPair". (In which case "delete" could be ill-defined if, as would be wise, the distance is computed from a lat/long or road table lookup, and so there is no actual database entry that corresponds to the distance between the cities.) That's the problem with REST: it doesn't avoid the complexity of RPC; it just crams it into ever-more-creative resource types.

Most API users (sorry, "consumers") would prefer they just be told the format in which to ask for the data, not have to re-discover it through gradually-exposed paths each time.


> what resource is it acting on?

The distance between the two cities.

> You have to come up with some added, unnecessary, implementation-exposing abstraction like "CityPair".

This is a really weird thing to say. No, you don't. I have no idea why you would think that.

> What are the four CRUD operations for it? [...] In which case "delete" could be ill-defined

Not every method has to be valid for every resource. It's a total non-issue that you can't delete a distance.

(And POST/GET/PUT/DELETE is a very different concept from CRUD.)


>>what resource is it acting on?

>The distance between the two cities.

Don't be cute. What server resource is it acting on? The value of the distances is (potentially) computed by some encapsulated algorithm -- you're not acting on that resource. The server resources that are touched are the two cities, and then whatever it does behind the scenes.

>This is a really weird thing to say. No, you don't. I have no idea why you would think that.

Because I'm not GETing a city, so I can't use the GET operation on the city resource; I have to make another resource to GET. Fine, it doesn't have to be a city pair: but there is a many-to-many mapping, which in REST-favoring frameworks (e.g. Rails), requires a separate table. By reducing everything to CRUD, you must create a new resource (type) for each new operation.

>(And POST/GET/PUT/DELETE is a very different concept from CRUD.)

That's a non-standard definition of "very different", considering that POST is create, GET is retrieve, PUT is update, and DELETE is delete.


GET /cityDistance?city1=Chicago&city2=Austin

Also, while POST can mean "create", it can also mean "append" or "process some arbitrary request."


>GET /cityDistance?city1=Chicago&city2=Austin

Yep! Works like a charm, until you have to expose a URI pointing to every combination of cities (or indeed, combination of any parameter set).

And I know (like I said before) you can fall back on "no, just tell the user where to put the parameters and you won't have to do that!" ... which is just re-inventing the RPC -- and satisfying users that don't want to navigate a long session just to find the URI they want, every time they send a request.

>Also, while POST can mean "create", it can also mean "append" or "process some arbitrary request."

Used correctly, it doesn't mean (that the sender is requesting that you) "process some arbitrary request"; it should only be used for non-idempotent operations. Close enough to summarize as "create" (appending is certainly creating something in this context!), and generally, for something to have different effects when repeated, you have to create something. PUT/update and DELETE/delete are idempotent specifically because the changes they make aren't creations.

In any case it's clearly an abuse of the term "very different concept from" in the GGP's comment "And POST/GET/PUT/DELETE is a very different concept from CRUD".


Nobody ever said that you should use REST if it doesn't suit the problem you're trying to solve.


But there are people that believe REST suits every API problem, even when accumulated wisdom says it doesn't suit the problem (cough Roy Fielding).


No, he makes it quite clear that it's a solution designed for a particular problem space. You're debating a straw man.


Indeed: the problem space being APIs. Feel free to point me to an example of fielding pointing to an API problem that shouldn't be RESTful.


No, the problem space being "scalability of component interactions, generality of interfaces, independent deployment of components, and intermediary components".

This merely happens to overlap significantly with the requirements of public APIs.

I have difficulty imagining your distance calculator needing any of those things, though.


>No, the problem space being "scalability of component interactions, ...

>I have difficulty imagining your distance calculator needing any of those things, though.

Right, because no one's stupid enough to use (or stick to the use of) REST for a distance calculator or any other algorithmically generated information. But make no mistake, scalability of component interaction is an issue, just a solved one (for those that see REST for what it is).

The solution is: specify an input scheme (for a hand calculator: put the first number, then plus, then the second number, then equals) and let the user choose the inputs. This saves you from the (intercomponent-unscalable) combinatorial explosion in which you have to give the user a link to every possible computation as they navigate the interface, and which is the REST method.

So, any exposed function in which you can't feasibly blast every possible input set over the network is REST-incompatible, so I guess the serious RESTers don't think you should do it. Which kinda makes it little more than a footnote.


I'm pretty sure Google's home page doesn't include every possible search term for you to select from, and that's a perfectly RESTful example of an exposed function (search). Forms are a very powerful hypermedia construct.


In the context of a website, maybe you can have a helper like that to avoid the REST bloat. But the architecture is for arbitrary APIs, existing outside of web pages, in which I don't have a neatly visible form. All I'm allowed to do is give the user URIs to choose from.

Some kinds of apps (esp those that can't tolerate the overhead of REST, like for mobile) need to know how to format a Google search request without navigating through a session on Google site, but just knowing what it should look like, and formatting it that way. REST would restrict you to pointing them to google.com and following links; it prohibits you from saying, "hey, you can have your app just point to google.com, then '?q=', then your search terms connected by +'s".


Part of the debate is what problems REST is suited to solve. While most evangelists will never come out and say, "you should use X for everything," they will try to fit it into whatever situation it will "reasonably" fit into, which is probably a bigger domain than the problems it's "best" for.


The thesis lays out in detail what REST provides:

"REST provides a set of architectural constraints that, when applied as a whole, emphasizes scalability of component interactions, generality of interfaces, independent deployment of components, and intermediary components to reduce interaction latency, enforce security, and encapsulate legacy systems."

The existence of these properties should be fairly evident when you examine the constraints.

I think large part of the confusion comes from not recognizing the difference between "Any system can be built in a RESTful style" (this is true) and "Every system should be built in a RESTful style" (this is a straw man).


That tagline may explain the benefits of REST, but it doesn't really explain at all which problems REST is well-suited for and which not.

I've found that REST design is great for problems where the most visible abstraction is a document or an object (with operations or functions as secondary). It doesn't really fit problems where the most common abstraction is a function call (with the arguments a secondary concern).


We're talking about two totally different kinds of problems.

You're talking about wire formats and structures that feel natural to use for particular kinds of calculations. I'm talking about recognizing properties that we might need a particular system to have (ease of use being only one of them), and ensuring them.

The line I quoted tells us exactly which problems (in the sense that I'm talking about) REST is suited for: the ones where those benefits are needed (and where the tradeoffs aren't to costly).


Not true.

GET /distance?cities=San+Francisco,Los+Angeles would suffice. city1=modesto&city2=fresno might be preferred if you wanted to support form submissions, too.

Query strings are perfectly restful.


That just shows it's HTTPful, not RESTful. In this case, that protocol involves being told how to construct a URI rather than it being presented from a menu of choices discovered by following URIs in the API.

I agree that it's much more convenient to have well-defined fill-in-the-blank. I disagree that it matches the requirements of REST, whose proponents always tell me "If you document the URIs or how to build them, you're doing it wrong."

http://stackoverflow.com/questions/1164154/is-that-rest-api-...


> involves being told how to construct a URI

The crucial thing that you're missing is that it's being told how to construct that URI in-band. Not in a piece of documentation that has to be hard-coded into the client.


So, once again, it turns out that REST reduces to RPC plus some advisable practices as soon as you point out how the original REST schema is woefully impractical.

Not-REST: You can algorithmically generate requests for the information you want based on documentation.

REST: You can algorithmically generate requests for the information you want based on documentation that's provided in the session. (Oh, and forget all that crap we said about URIs having to be presented to the API consumer as part of session's hyperlink navigation.)

So, now I can turn RPC into REST just by slapping a link to the documentation on every response (and maybe moving verbs to the appropriate HTTP request type, even though that has nothing to do with CRUD[1])? Gee, why didn't you say so?

[1] http://news.ycombinator.com/item?id=4811969


No.

You're not listening, and you're not arguing in good faith.


I could say the same of you. Please tell me how I failed to accurately characterize the difference between RPC and REST with respect to defining requests whose entire working URI set can't feasibly be sent over the network.

Alternatively, explain how REST can simultaneously meet the constraints of "avoid combinatorial explosion of possible URIs to explicitly present" and "every resource is accessible by following server-provided links" and "avoid unnecessary bandwidth usage".


If thats truly required (i dont think it is), the second example could be shown via introspection.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: