Hacker News new | past | comments | ask | show | jobs | submit login
Dudes, this is so not REST (mooseyard.com)
310 points by mccutchen on March 15, 2011 | hide | past | favorite | 130 comments



After reading the title I was all set to come in here and complain about "REST" Nazis and make some comment about how real life situations tend to supersede strict adherence to conventions.

But then I read the article and I have to admit this is a pretty egregious break with how REST services are supposed to work.


I came here to say the same thing. For those of you who aren't going to bother reading the Rdio API spec (I did, because there's something I want to hack together with it): the whole API is literally just a single URI that accepts a "method" param, where the method is a list of verbs like "get all tracks in this playlist" or "add a friend".

There's a case to be made for relaxing the definition of REST to accept "just a bunch of URIs" APIs that don't follow the discoverability/transparency conventions of REST. But you can't call "here's a list of verbs" a REST interface.

What you'd want to see in a Rdio REST interface would be:

* /rdio/api/1/playlists * /rdio/api/1/playlist/foo * /rdio/api/1/artist/1 * /rdio/api/1/artist/1/tracks/2

&c &c &c. But, from what I can tell, none of the state inside Rdio's database is mapped to a URI.


I don't like API version numbers in the URI.

It implies that a resource is different just because you are using a newer version of the API.

My own most recent implementations use Accept: and Content-Type to define version compatibility, which is what content negotiation is supposed to be about.

Versioning in the old web API sense meant changing the way the protocol works, and REST will always be REST and the resources will always be resources.

All that is likely to change between 'API versions' is formats, which you negotiate with headers, and adding new fields, which old clients can either ask not to get through content negotiation or can safely ignore.


I can see it both ways.

APIv2 is not the same resource as APIv1, so why send it to the same location? Similarly, APIv1/user/1 may very well not contain the same information as APIv2/user/1, so are they really the same resource? They likely refer to the same semantic resource, but if user/1 != user/1, they're not the same from a data standpoint, which is what APIs are generally used for.


It is the same resource. User #1 is the resource. The URL refers to the user, or the user's account. Unless the user creates a new account for use with API v2, the URL should be the same. API v1 and v2 may represent the resource differently, but they are the same resource and should have the same URL.

The correct method for selecting a specific representation is to use the Accept header on the request. For example, if I were requesting somedomain.com/Groxx I could specify Accept: image/png if I wanted a picture of you, or Accept: text/x-vcard if I wanted your contact information.


I believe you are incorrect. From the 1.1 spec:

"The Accept request-header can be used to specify certain media types which are acceptable for the response."

Similar to how when you access some linked data URLs you can specify rdf/xml or rdf/n3 in the Accept header to receive the same data in a specific format.

It's not used to specify whether you want a picture of someone or their contact information all from the same URL.


The REST folk disagree with you. If the picture and the contact information are different representations of the same resource (which is not that much of a stretch conceptually), then they absolutely should be reached at the same URL. At that point, the only way you have left to distinguish what you want is the mime type.


Out of curiosity: how do the REST folk feel about differentiating between resources with urls like /user/1.json and /usr/1.html ? That has been pretty popular, from the little I've seen, and has the advantage of being GET-able with a browser, where header modification is not.


You should use content negotiation for this. The client should have an Accept header that specifies what it wants (which could be "application/json" but really should be something that tells you more about the contents than simply how it can be parsed, such as "application/vnd.mything.MyResource+json" which would be documented in your API with what fields it contains and what it means etc.).

You should also question whether you really need multiple representations for each resource -- in many cases, it's more trouble than it's worth to automatically generate, say, both JSON and XML responses, since it just divides your attention to creating sensible serializations for your API.

If you expect to have clients which cannot modify the headers of their requests, you can support fallbacks like specifying the Accept header in a query parameter. Putting it in the actual URL though is doing a disservice to fully compatible HTTP clients, though.

But if JSON is so inherent to the resource that content negotiation doesn't even matter, it can be fine to include that in the URL, as you might include descriptive filename extensions like ".png" or ".wav" in a URL.


That is still a case of using two URIs to refer to the same resource. If you use one URI per resource, URIs (and bookmarks) can be shared between clients dealing with different media types. Suffixed URIs require mangling to request a different media type.

Clearly it is a pragmatic trade-off and is popular (Google and Twitter do it). The correct answer will be arrived at by considering the total architecture of your application.


As soon as you decide to create two URLs such as /user/1.json and /usr/1.html you are creating two distinct resources. The litmus test for determining if two URLs refer to the same resource is you do a GET on both and only one of them returns a 200 the other returns a 303 with the Location header set to the URL that returned a 200.


That's a good reason to differentiate by header (plus no .jpg vs .jpeg shenanigans in the url). Though I can't say I've ever heard of it being used... I'll have to keep it in mind if I'm ever architecting something that anticipates many different kinds of clients in a large API, however.


Not sure how all REST folk feel, but Roy doesn't have any problem with using the convention of file extensions to indicate resources with different formats. http://tech.groups.yahoo.com/group/rest-discuss/message/1396...


Well, to be clear, he says you should certainly use the Accept header, and if you want to be nice you should provide the formatted URLs as well.


Yeah, but he's explicitly saying that they are different resources with differing types, not the same one with differing types.


Wrong in theory, inevitable (or at least pragmatic) in practice.


If version 1 of a resource is not a subset of version 2 of a resource, and they are not accessing the same record, then they should be separate resources

what 'API' is signaling is what the client is capable of understanding, which is what content negotiation headers are for

I think of it no different to the same resources for web browser consumption (for humans) - I don't place new designs of a website into /design1/ /design2/ etc.


Bear in mind the more things like "Well, you just have to properly use the content negotiation headers" you add to your API, the more the "simplicity" argument of REST goes out the window. I'm not sure I've ever seen really correct use of the content-negotiation headers and claiming it's a solution is dubious... sort of like how I'm still waiting to see proper use of XML Namespaces in the wild. They seem relatively simple to me but the evidence suggests strongly otherwise.

That doesn't make REST "bad", but I think it does start to make the quasi-religious aspect of it less obviously correct.


That's part of my reasoning. Setting proper headers is, yes, more proper... and something essentially nobody does, and many simple API libraries don't support without making using them massively more complicated than prefixing all the URLs with "api/2".

It's a correctness vs usability debate. I'd love to go for correct, but it's extremely painful to enforce in your users in practice.


Using content negotiation, I can--if the server supports it--take the same URI (e.g. http://www.jerf.org/) and pass it to an image viewer to see your face, to my address book to fetch your contact info, etc.

Anything else requires the client knowing how to mangle URIs (e.g. adding /avatar.jpg, /contact.vcf).


I know what content negotiation is; I've never seen it done right. The theory is all beautiful but in practice content negotiation never seems to work right because you never get two people to agree very well on what things are. Another manifestation of the usual semantic classification problem.

It has a dubious track record in X as well. X has been able to do content negotiation for decades for the clipboard but even now it's still spotty and buggy, and that's with everything actually running on the same system. It looks easy. Heck, it looks very easy. It isn't. I can't even tell you exactly why it isn't as easy as it looks (beyond the semantic thing I mentioned above), but the state of the world is pretty clear.


What, realistically, is the difference between knowing how to mangle URIs vs. knowing what content types are available for negotiation?


@awj: if your API does HATEOAS properly, so that your responses inline URLs to other related resources (aiding discoverability of your API through hypertext), then the client can naively take the URLs given to it and cleanly apply Accept headers to them as appropriate.


if you don't want to use content negotiation, then stuff it into query parameters - that is what most API's do (and most that support full content negotiation do anyway)

eg.?v=1&format=xml

but interesting to note is that why is encoding easy to do as part of content negotiation, yet everything else is hard? you never see ?e=UTF-8 or &c=gzip


Many APIs simply specify that the encoding is constant (always UTF-8) so this is not an issue. And many HTTP libraries simply handle the content encoding transparently.

The challenge is some HTTP library APIs commonly used for developing clients offer the following interface: - GET $URL

If you are lucky, then it might also support POST and offer a second parameter for the request body. If are really lucky, there is a way to specify arbitrary methods, but this is fairly rare.


I'm all in favor of supporting fallbacks for more limited clients. But query params are not a great idea since they can prevent caching from happening.


Add a random number to the end as a param to force no-caching.


My point was that it's not a good thing for requests for cacheable content, that might not be cached since you used a query param to access it. Some caches ignore requests with query params since "queries" are often not static.


I completely agree from a pure REST perspective, but if you want developers to be able to quickly get up to speed with your API, requiring them to know the finer points of HTTP and how to manipulate headers within their clients is asking a lot.


Is it though? They are developers, developing applications for the web. I don't think its a huge barrier to expect people to learn the basic protocols, and tools like curl reasonably well.


Do you have full control over the clients which make requests (e.g. it's only AJAX or 3rd party clients written to your api spec - i.e. not browsers making raw requests against some of your urls?)

I backed away from using content-negotiation for an API, part of which would have served data and part content.

e.g. to access file metadata, get /path/to/file with Accept: api/v1 and do a 'normal' GET to get the file contents.

I came across some suggestions that some browsers (recent IE I think, unsure) which suggested that cacheing was broken wrt Accept header - which made me worry that people hitting accessing the resource might get the wrong version.

I don't know if your api is vulnerable to this, if you've come across the problem or have any deployment wisdom to share.


The problem is the data model may change between versions so the URL hierarchy will change. Or instance you may have split customer and staff into separate concepts but later decide your service is better imagined as a network and thus only have users.


How do you do authentication?


With the methods provided via HTTP.


> What you'd want to see in a Rdio REST interface would be:

You should disclaim that these URLs could just as well be

* /rdio?q=1&s=63

* /rdio?q=1&s=63-8

* /rdio/4E7?q=1

* /rdio/4E63?q=1

and still be part of a RESTful API.


No, those are not part of a REST API. You've got it wrong.


Besides simply asserting the OP is wrong, perhaps you could explain what differences (aside from aesthetics) there are between

    /rdio/api/1/artist/1/tracks/2
and

    /rdio?api=1&artist=1&tracks=2
Routing code on the server can treat them as identical; is there anything about these two URL formats that would trip up a client?

Does it change how caching might work?


With the first format you can use the same name more than once:

    /rdio/api/1/artist/1/tracks/2/artist/1
I'm pretty sure the ordering of query parameters isn't a part of the HTTP spec.

I just did a quick check and Django, for example, will just take the second of any duplicated GET params.


Ordering of query parameters is a W3C recommendation:

  http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type
If Django's ignoring repeated form fields, it's Doing It Wrong.


You're right about the ordering, so I guess Django is actually doing it wrong.


You have to use the "getlist" method instead of "get" if you are expecting multiple values.


well I believe both are not correct.

the idea is that you can build a generic 'REST' client and point it to almost anything that is a 'REST API' and it will work, in the same way we can now with web browsers

a REST client will never figure out /api/1/ - which is why resources go in the path and query parameters go in as, well, query parameters :)

from the server side you are right that modern front controllers and routing can make it all the same (heck, I can route resources to different subdomains, if I want), but a proxy does not know what the front controller logic is (ie. working backwards to what part is what).


> the idea is that you can build a generic 'REST' client and point it to almost anything that is a 'REST API' and it will work, in the same way we can now with web browsers

That's a stupid idea. REST is built on two things: content types and resource location. The content types indicate the meaning and location of the resources, if the client does not understand the content-type, it can not do anything.

You can not "build a generic 'REST' client and point it to almost anything that is a 'REST API' and it will work", that makes no sense. Indeed, that's not what web browsers do: the driver of the API on a website is the user, not the browser.

> a REST client will never figure out /api/1/ - which is why resources go in the path and query parameters go in as, well, query parameters :)

That's completely irrelevant.


> That's a stupid idea. REST is built on two things: content types and resource location.

here is what my generic REST client looks like:

* HTTP[s] * JSON * Atom and RSS * Caching layer

some controller login in between all of these. I inherit this to implement simple models and controllers in the client and just tell it which resources I want (like fields in a database)

how is that not a generic client?

for twitter I have classes called users and statuses, with each method defined. for google I have similar classes. this all took minutes for me to get working - I thought that was the entire point of REST?

read the original desertion, sec. 5.2.2 connectors:

http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch...

> if the client does not understand the content-type, it can not do anything.

generic doesn't mean understanding the payload, it means understanding the protocol


The latter can break caching for some older proxies.

Also, I believe safari will ignore your caching/expires headers if you use GET params.


Actually URLs are supposd to be opaque in rest so that is correct.

Nice urls with http verbs but no hateos is what most "REST" APIs are though.


Behold, the know-nothing.

Sorry sir, I'm not wrong, those would be perfectly valid as part of a REST service, including as alternatives to tptacek's description. Readability of the URLs has nothing at all to do with RESTfullness.

The only thing REST says about the data transmitted (the URL in this case) is that it's the container for the application's state, and most interpretations of this is that the URL is entirely opaque. And indeed, Fielding has suggested/explained this several times.


You could have defended your point without the name calling. You're just undermining your otherwise correct point with crap like that.


See http://en.wikipedia.org/wiki/Representational_State_Transfer

Those are not REST because they are not resource-based.

Correct REST:

http://blah.com/widget/:id - GET, PUT, POST, DELETE

How does that fit with your /rdio/4E7?q=1 ? Where's the resource? What is the id? What is q anyway?

You can pass parameters with a ? in REST... for example, you might do

GET http://blah.com/resource/123?format=xml

But there's still a clearly identified resource which the GET is performed on.

Sure, technically, by stretching things a bit, you could claim that /rdio?q=1&s=63-8 is a REST GET request for resource id "63-8".

And, technically, you'd be right, much like technically, this is valid C: http://stackoverflow.com/questions/18642/what-is-the-most-un...

But just because it's valid doesn't mean it's in any way good. Those are horrible examples. So no, those URLs could not "just as well" be those nasty examples you give. They could, much more poorly, be those examples, and still be technically valid. By the same reasoning, "Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo" is just as good english as Shakespeare.


PLEASE do not use the Wikipedia article as a citation. It's historically so full of misunderstandings that even Roy Felding himself has said it's nonsensical. This is a case where Wikipedia isn't quite "good enough" to let slip as a proper source for an argument.

Your arguments about nice looking URLs in fact have absolutely nothing to do with REST, except that REST says you must use your transport protocol according to its standards, where appropriate. It says nothing about how URLs should look. I you're talking about the HTTP spec, call it by its proper name please. We don't gain much from conflating different terms like this, it's just a source of confusion.


All query string parameters are used to identify the resource also. RFC 3986 states "The query component contains non-hierarchical data that, along with data in the path component (Section 3.3), serves to identify a resource within the scope of the URI's scheme and naming authority (if any)."

There is absolutely no difference between path segments and query parameters from the perspective of resource identification.


Then the RFC has defined a fairly useless standard. Wouldn't be the first time.


A good rule of thumb here seems to be to put identity in the path and other things in the query string. For example, to search for items with property foo equal to 12 in the music collection known as bar, the url would be /music/bar?foo=12


I agree. I recently built an API for a project of mine and I decided to make it REST-like, but not use the HTTP method to distinguish actions. In some circumstances you can only use one (JSONP, for example), so I sacrificed some purity for "the real world". This seems like it goes a bit over the line, however.


Actually, what the blog author is talking about is a resource-oriented architecture (ROA), which is typically implemented in a RESTful fashion over HTTP but has recently been conflated with REST itself. ROA != REST.


Just to amplify: there's more than a pedantic difference beteen the two. REST has a lot of serious advantages related not only to application architecture and interoperability but also to system architecture and scalability. There's a lot in the original REST dissertation about removing shared state and enabling cacheability.

The crowd that mistakes ROA for REST (I think) sees the stuff in REST that relates directly to development and gets excited - but the stuff related to making their app scale, they ignore. If you don't want to learn a little bit about everything, at least follow the rules that relate to the things you don't know about.


"we'll make the URLs pretty, but we'll ignore the stuff about statelessness."


Exactly. ReST as a concept is not even tied to HTTP. HTTP's design was just heavily influenced my ReST so it happens to be good at it. Somehow people are obsessed over URL formatting and HTTP specificities... while they are important, it's not the literal embodiment of what representation state transfer is, just an implementation of it.

What most people talk about when they say REST are good HTTP practices. Meaningful URLs, proper methods, etc... are all about using HTTP properly. We can call some of these views other acronyms like ROA but it's really just appreciation for proper and modern HTTP stacks.


> HTTP's design was just heavily influenced my ReST so it happens to be good at it.

REST was extracted from HTTP. It's not that HTTP was influenced by REST, it's the exact opposite, REST is a formalization of HTTP.


Actually, that's not true. ReST was developed in parallel with HTTP 1.1. It used the basics from HTTP 1.0 to express some of the new ideas. You can read about the original idea in Fielding's disertation here: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch...

If it were an extraction of anything, it wouldn't have been HTTP but existing ideas in scaling web architectures in general at the time.


Thank you for calling a spade a spade! The author talks about REST being object-oriented when it is actually resource-oriented. I know I'm flirting with pedantry for getting worked up about this, but anyone who knows what "object-oriented" actually means is either lying or ignorant of the manifold meanings associated with that term.


Why does it matter? Ok, I agree that you probably shouldn't label something with an incorrect term, but does not having more than one URL, and not using the different HTTP methods really make a difference in terms of programmer usability?

I personally find that sometimes I have trouble spotting the "oh! I forgot to make it DELETE instead of GET" bugs. When the parameters of the API are all in the url and/or query, it feels better encapsulated.

(promise I'm not flaming, and I fully expect to get told, yes it matters, and here's why! ;)


does not having more than one URL, and not using the different HTTP methods really make a difference in terms of programmer usability?

Yes. You can use libraries when the service you're trying to interact with works according to some standard.

An example: I have an app I wrote at work that is a JavaScript frontend powered by a REST API backend. The REST API tries to be a good REST citizen: proper HTTP implementation (201 + Location when something is created, 202 for "I will get to that eventually", etc.), consistent URL conventions, and a consistent data format.

The end result is an API that is easy for humans to understand, but also easy for computers to understand: the simple CRUD code was about 10 lines of backbone.js, because my API doesn't break any conventions. This means that the code to interact with it already exists, and all I had to do was make the web page look pretty.

This is a good use of programmer resources, now and in the future. In the present, I didn't have to do any work to make a pretty GUI. In the future, someone that wants to pull data from my API will not have to swear at me -- everything you can do is easily discoverable by starting from the root resource.


You can have a well-defined spec that's easy to understand without having to shoe-horn your API into HTTP's document-orientated semantics.


Sure, just don't call it REST.


Yes. In this case, it makes an enormous difference. Your application can't just go to rdio/api/1/artist/whatever to look up the tracks for an artist; it has to make a SOAP-style request for the tracks for a given artist. This isn't a style nit.


In trying to prove you wrong and show you how easy it would be to make a similar call with the rdio API, I found out how not easy it would be to make a similar call with the rdio API. :)


No, it's not REST, and it's stupid to call it that, but if you think that posting a few arguments makes something "SOAP-style", I find it hard to believe you've interacted with a SOAP web service recently..

Note: Requiring that the call are OAuth'ed, doesn't affect its RESTness.


It can probably be argued to be: you can't just go to rdio/api/1/artist/whatever, but you can get the exact same thing via RPC calls.

I often think that, via REST APIs and content negotiations, API can become browseable and self-descriptive but I've yet to see any example of such a thing. Furthermore, just because an API is restful doesn't mean it's well-designed, and doesn't mean it has descriptive APIs (the artist's track could just as well be in rdio/api/64D89CAC?q=42, that wouldn't inherently make the API non-restful)


> I often think that, via REST APIs and content negotiations, API can become browseable and self-descriptive but I've yet to see any example of such a thing.

It should be trivial with AtomPub/GData/OData APIs. REST itself is not specific enough for that.


HTTP makes some simple guarantees in its spec regarding to the methods used. For example, GET must never have side effects. POST, PUT, DELETE always have side effects. This simple guarantees enable software like HTTP proxies to work properly. Thus by just abiding to that simple rules your API should become cachable.

What REST brings to table is exchanging representations. For one thing, it makes your API actually simpler, since you don't even need a list of 'methods' like rdio has, all you need to know is the representations and methods stay the same—which should come natural if you know HTTP.

The other nice thing that you get for free is that it accommodates for unreliable connectivity. In case of failure you can just retry. OTOH RPC abstracts such things away. For example if you have a call like "addSomethingToList" and you retry that method, you risk having duplicates.


GET is idempotent. It's fine if the first GET request to a resource has side effects (like creating it on demand).


GET must never have side effects. POST, PUT, DELETE always have side effects.

Pedantry: because they're supposed to be idempotent, POST, PUT, and DELETE should only have side-effects the first time they're issued against a given resource.

Also, RFC 2616 uses "SHOULD NOT", as opposed to "MUST NOT" to describe the behavior of the "safe methods". To wit, "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."


POST is not idempotent. POST is explicitly what you should use for non-idempotent operations.

This is why your web browser issues "need to resend a form" warnings when you return to earlier pages.


Oops. Looks like, when I double-checked the RFC, my brain stuck POST in there. That'll show me for trying to be pedantic in the middle of doing thirteen other things.

Thanks for the correction.


POST is not defined to be idempotent, although you're correct about PUT and DELETE.


> HTTP makes some simple guarantees in its spec regarding to the methods used. For example, GET must never have side effects. POST, PUT, DELETE always have side effects.

Except those are of course guidelines, the API implementor is free to entirely disregard them (much to the danger of everybody)

> For one thing, it makes your API actually simpler, since you don't actually need a list of 'methods' like rdio has, all you need to know is the representations and methods stay the same—which should be natural if you know HTTP.

Instead of a list of methods, you get a list of methods (which do not have to stay the same, by the way) and a tree of resources. Theoretically you should be able to crawl a REST API using only the document types and the root URL, I don't think I've ever seen a "public" API letting me that.

> OTOH RPC abstract such things away. For example if you have call like "addSomethingToList" and you retry that method you risk having duplicates.

Yes, because if you POST the same thing twice you don't risk fucking things up...

Oh you should be using PUT, not POST, you say? Good luck getting that one in browsers.


Okay, first this was of course nit-picking, as I just hoped to get across the point, that REST is not just pretty URLs.

> Except those are of course guidelines

Well, obviously.

> Instead of a list of methods, you get a list of methods (which do not have to stay the same, by the way) and a tree of resources.

Well, yes. But those are already established and if you're exchanging representations as REST demands, you shouldn't need anything more than GET, POST, PUT, DELETE and PATCH to manipulate data.

> Theoretically you should be able to crawl a REST API using only the document types and the root URL, I don't think I've ever seen a "public" API letting me that.

Sun tried to do that for their cloud computing API, I think they're the ones that created the term RESTful where you'd use elegant concepts like <link> in your representations to advertise available actions.

> Yes, because if you POST the same thing twice you don't risk fucking things up...

If you do it properly with versioning/unique ids where appropriate, then all your calls should be re-triable or at least fail.

> Oh you should be using PUT, not POST, you say? Good luck getting that one in browsers.

You can create browser API (with proper CSRF protection etc. btw) that acts as a [server-side] client to your REST API. Also I see most usage of any REST APIs from browsers coming from Javascript based clients, which usually don't impose such limitations.


> that REST is not just pretty URLs.

REST and pretty URLs are very much orthogonal indeed.


>Instead of a list of methods, you get a list of methods (which do not have to stay the same, by the way) and a tree of resources. Theoretically you should be able to crawl a REST API using only the document types and the root URL, I don't think I've ever seen a "public" API letting me that.

Oh yes you have. Ever browsed a ftp server with your browser? That is a REST API, using HTTP and FTP for transportation and HTML and WHATEVER for the actual data. You can start from the root of the server (or more commonly, from /pub/) and crawl through the file hierarchy as much as you like.

But your point is valid. Not many APIs allow to "crawl" the data, even though one of the four guiding principles for interface is: Hypermedia as the engine of application state "If it is likely that the client will want to access related resources, these should be identified in the representation returned, for example by providing their URIs in sufficient context, such as hypertext links."

REST is an architecture style, not a protocol. HTTP is protocol well suited for use in a RESTful system. The API in question violates REST (atleast) by not using the methods provided by HTTP.


> Except those are of course guidelines, the API implementor is free to entirely disregard them (much to the danger of everybody)

Witness the Google Web Accelerator debacle.



> but does not having more than one URL, and not using the different HTTP methods really make a difference in terms of programmer usability?

If you're expecting a REST API yes. It also significantly impairs the discovery and the cacheability of the API calls.


I once worked on a project where 'REST' was synonymous with 'putting query data into the URL before the query string', and this was done so that the webserver could cache the response.

I died a little inside every time I wrote a 'Restful' servlet there.


This is an increasingly common extension of the REST paradigm. Google ran into a number of problems with the restrictions of REST, so their new APIs all work this way. See their justification in this video: http://www.google.com/events/io/2010/sessions/how-google-bui...


Slide 87 of the pdf has the best summary, but the main thing w/r/r REST is that get/put of entire resources can be too heavy.

1. custom methods let you get/put specific fields, without having to transfer the whole thing or split resources up as you add new methods.

2. custom methods avoid needing to implement complex or heavy state mutations on the client. the example was rotating an image 90 degrees; you wouldn't want to download an entire full-res image to your wimpy battery-powered phone, rotate it, and re-upload it when you can just do that on the server.

(... of course this should just update some orientation metadata instead of resampling the image -- it's just an example)


As for your point 2, if you consider a REST resource as a collection of fields, you can update it without custom verbs:

  GET /resources/picture/orientation => 0
  PUT /resources/picture/orientation?value=90
REST is not so much about a simple API, but a scalable service. Custom verbs break scalability.


I believe the issue with Rdio is not that they need custom methods, their API should just be GET, PUT, POST, DELETE, etc. but that they are passing what should be the resource as a parameter


Those are not restrictions to REST, since REST doesn't make any specific claims about how to use things like filtering, sorting etc.

Google created GData2 as an extension to AtomPub format, which only specifies a common envelope for resources (Atom Syndication Format) and how to talk about collections of resources (AtomPub itself).

There is another notable extension to AtomPub format from Microsoft called OData.


Note that there's also a pdf if you don't have the time for the whole video.


'''Maybe we should just give up on the term REST, since it’s become so diluted as to mean nothing more than "HTTP API that’s not as hard to use as SOAP"?'''

To be fair, I thought we were at this point already. It seems safer to assume that when one advertises a "RESTful API" they are really referring to a "REST-like" API which basically means "Hey, we don't use sessions!"

While I believe that the term is already diluted to that point, I still think it's valid to point out when people are doing it wrong.


It's diluted for sure, but it still carries a strict interpretation that is worthwhile and that some of us are still using.

My main problem with its dilution is that it's usually totally meaningless -- usually other terms like RPC or just plain old "proper HTTP" accurately describe what someone is calling REST, to there point where its supposed RESTfulness can be nothing more than for the sake of buzzword compliance.


REST is now just a generic term for any HTTP API that's not SOAP. Like Xerox and Kleenex, the popular usage is technically incorrect, but in practice, it doesn't matter.

Most REST API consumers today are more like CURL than a web browser. In the CURL-like case, the RPC pattern works quite well. HATEOS and other browser-centric REST ideas often just don't fit naturally into a simple API consuming app. People need to move on.


"Like Xerox and Kleenex, the popular usage is technically incorrect, but in practice, it doesn't matter."

The integrity of some acronyms is worth defending. I wouldn't want 'ACID' diluted to mean anything less than its strict definition, and I think the same holds true for 'REST'. The benefit of these distinctions is twofold: 1) we encourage the advantages of good RESTful practices and 2) we can communicate consistently without spending unnecessary effort qualifying our meaning. If REST means 'Anything but SOAP' then at some point we'll have to come up with another shorthand for 'Real REST' or spend lots of time re-stating the principles of REST every time we need to communicate architectural strategies that use them.

I should be able to say 'Singleton' or 'MVC' or 'ACID' and know that there is enough integrity to those ideas that a competent coder will know what I mean without me having to pseudo-code or UML the concept for them. The same should hold true for REST.


Except that there was already a perfectly good name for that: RPC. REST was defined in contrast to RPC, so calling an API that involves "POST to this URL with the method as a parameter" REST is really unnecessarily confusing.


> REST is now just a generic term for any HTTP API that's not SOAP.

So you're telling me I should call my XML-RPC APIs REST?


"It screams RPC. There is so much coupling on display that it should be given an X rating."

-- Roy Fielding @ http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte...


This sort of API is not RESTful at all, regardless of whether the method name is in the HTTP header or a form variable. It's still an application-specific protocol that requires out-of-band knowledge to use. REST resources are supposed to be self-describing, which doesn't make much sense for an API like this. RPC is what is required here, so just tunnel RPC over HTTP in whatever way is most practical. And don't call it REST.

If you want a bucket of cold water over the head on this topic: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte...


Instead of fetishizing REST for its own sake, how about appreciating an HTTP API that can be used (read/written) with a browser via form elements and hrefs?


Instead of fetishizing horses, why not appreciate this butterfly that I'm calling a horse?

http://www.youtube.com/watch?v=Sv5woNs9WRE

Being accurate with a technical term is not a 'fetish.'


This can be done on top of REST API with your server acting as a client to your own API. Actually, that way it'll probably be possible to implement it much safer.

And what's the use case anyway? Are you going to perform those requests from other domains and authenticating via cookies on your own? How do you protect from CSRF doing that? What's wrong with OAuth 2.0 + JS?


I completely agree with you. There will always be a contingent of developers who believe enforced standards trump simplicity. As we see here, when the CORBA then SOAP crowd realized they'd lost that fight, their ilk started judging other projects by adherence to strict API structural definitions like formal "REST". That said, I do believe this constant dialog between ad-hoc simplicity and rigid standards is good for the industry; in each area, accepted practice evolves to meet the needs of its current application.


REST is as simple as it gets. You could make that argument if someone were to advocate using REST outside of HTTP. But HTTP is inherently REST, so you should have a good reason to not use REST rather than the other way around.


> REST is as simple as it gets.

It is not. It's quite complex actually. And I'm betting what most people who believe they have a clue think of "REST" is actually "RPC over pretty urls".


But that's just because of a general ignorance of how HTTP protocol works. If someone were to be explained, how it should work from the beginning, I'm sure they'd have no problem with grasping the subject.

Actually some Google engineers do a very good job of explaining how AtomPub and GData APIs work just with short Youtube videos.


A REST API should be simple to use. However, it is frequently not easy to build a simple REST API.


We might be getting close to this point: Maybe we should just give up on the term REST, since it’s become so diluted as to mean nothing more than “HTTP API that’s not as hard to use as SOAP”?

This is a shame, because RESTful APIs are (for me, anyway) usually a joy to build and to use.


There's already a specific term for the kind of API that rdio has: RPC. Remote Procedure Call.

I mean, come on, how can you say you have REST (with R standing for Representational) if you have section called “Methods” in your API documentation. HTTP API sounds okay, but in fact their API is not even HTTP specific (actually, it abuses HTTP).


> We might be getting close to this point: Maybe we should just give up on the term REST, since it’s become so diluted as to mean nothing more than “HTTP API that’s not as hard to use as SOAP”?

Well except RDIO's API is not any simpler to use than SOAP.

It's RPC to and through, let's call a procedure call a procedure call.


Yes, though this one's especially bad for not even bothering to use different URLs.


I've worked with APIs that return XML containing one node, which contains escaped XML. So when I read something like this it doesn't seem that bad.


That's fine. Just don't call it REST. Does buzzword compliance matter so much? Call it what it is: RPC.


In the Java world REST was pretty cool for about 18 months. And then annotations came out, and instead of all the JAX-RPC bondage and discipline, you get JAX-WS, where to make something a webservice literally all you need to do is shove the @WebService annotation on it and you are good to go†.

All the WSDL and SOAP crap gets auto-generated for you. Thereby eliminating in a single stroke REST's advantage.

Now, it is true that there is some stuff†† you can do with SOAP that you can't do with JAX-WS, but really unless you like making life difficult for yourself then don't.

Especially for a big Java to Java solution there doesn't seem to be any compelling reason to go with REST anymore. Even if everything you do maps exactly to the four SQL ops (select, update, insert, delete) it is still just as easy to use the annotation as it would be to use REST.

†C# has something similar I think.

††Example: JAX-WS is limited to what you can do with a method and parameters in Java. In your SOAP schema you can specify for instance that the array you get passed shall have between 1 and 3 members, two is okay but 4 is right out. Whereas in Java (and hence JAX-WS) if you have an Array parameter, you can't specify that it must have a certain number of elements in it.


The simplest method of creating SOAP-services is use of SQLServer SOAP Endpoint.

Just one line for SOAP from stored procedure or function.

Is it beautiful? I don't think so. SOAP remains SOAP, ugly remains ugly.


The author gives WebDAV as an example of a good standardized REST API.

Is adding new HTTP methods (like PROPFIND, MOVE, COPY, etc.) considered to be RESTful? I always thought you were supposed to structure all actions around the main 6, and add extra functionality in the data payload or query parameters.


FTA > In fact this is why Tim Berners-Lee used the word “method” in the HTTP protocol in the first place.

Does he have a source for this? Coincidentally I had just read the HTTP 0.9 the other day and I didn't see "method" being used that way at all. I think method, in HTTP, just means "a means to retrieve / put data", not method in the object oriented sense.


Yep, our API isn't really technically REST in the classical use of the term. We changed some of our wording and made a blog post: http://developer.rdio.com/blog/read/No_REST_for_the_wicked


Summary:

Rdo: "Yeah, we have POST!"

Thought Palace: "What about the rest?"


This is a good example of a REST anti pattern. It can be easier to understand REST, when you know what it's not.


I am all with you on using GET and POST properly, but is there any REST API that actually uses PUT and DELETE?


Take a look at Sun Cloud API. It's one of the best examples.

For APIs that need regular browser support, it's fine to add fallbacks like query params to specify PUT or DELETE. But these are hacks.


Yes! Yes! Yes!

"HTTP API that’s not as hard to use as SOAP"

My current employer calls our API ...

... RESTful like .


It’s object-oriented, where objects are identified by URLs

I'm not so sure that "object-oriented" is the right term here, but totally agree with the premise: this isn't REST. It's more like XML-RPC Jr.


So it's an HTTP-based API rather than true REST. Move on. shrug


how about calling it RESTish? http://news.ycombinator.com/item?id=2242162


How about calling it what it is, namely RPC?


Yes. The terms "RESTish" or "lower REST" are just a way to stay buzzword compliant, not actually a way of elucidating anything. They're catch-all buzzword substitutes for more accurate terms.

They're particularly bad since a strict interpretation of REST can still be valuable, yet it makes REST itself seem overly nebulous and fluffy.

People advocating terms like "RESTish" or looser definitions of REST seem to think that REST is an ultimate goal of any decent web API. It's not, REST doesn't need to be used everywhere, your API isn't crap if it's not REST. So stop calling it REST like you're embarrassed to admit it's "just" RPC.

(Sorry for ranting in reply to you -- you seem to get it)


It's not RESTish.


lol whoops, forgot my sarcasm tags. i was not advocating calling anything RESTish.


Or "drowsy?"




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

Search: