
Nobody Understands REST or HTTP - shinvee
http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http
======
DanielRibeiro
This was posted 7 months ago on HN (with 510 points!):
<http://news.ycombinator.com/item?id=2724488>

Very lengthy discussion at that time.

~~~
walkon
I believe the author of this has refined/updated some of this thoughts since
that first post.

~~~
DanielRibeiro
I believe you are right. Also he is writting his own book:
<http://getsomere.st/> (linked from the part 2)

------
Argorak
The part about "accept-language" doesn't address the real problem. If I copy
the url to a piece of content that is available in 2 languages and send it to
someone else, I want them to read it in the same language as I originally read
it. Sadly, I cannot copy Accept-Headers in a fashion that "normal" people
understand. To me, resources written in 2 different languages may be instances
of the same thing, but not the same resource.

At worst, the page in question uses automatic translation (not so uncommon
when it comes to large knowledge bases), so the translation might be odd.

Basically, according to the article, Wikipedia has it all wrong.

~~~
almost
I think different approaches are suitable for different situations. Quite
often I think different translations of the same thing should be treated as
different (but related) resources.

~~~
Argorak
Sure, but the article makes it look like language encoded in the url is all
wrong, while I think that (most of the time) it is exactly what you want.
ACCEPT_LANGUAGE is a perfect for educated guessing of a users preferred
language, but not for referencing an article.

------
richardlblair
There are numerous opinions on the subject of RESTful apis. The author of this
post makes many good points, but I, like many of you disagree with his opinion
on versioning.

While putting the version into the header is clever, it reduces the usability
of your api. When you are designing a RESTful api you typically want to design
your api so that it is simple and easy to implement. Nothing is easier than
being able to explore an api via a web browser. If you make the user specify
versions in the header than they will have to install a browser plugin to
explore your api.

You have to consider that you aren't always "selling" to other developers who
understand http headers. You could be "selling" to non technical project
managers and CEOs who simply don't understand http headers. They do understand
URIs, though. So if you can provide these people with a URI that just works,
and they can poke around and see data they have a greater chance of
understanding and getting excited about your API.

------
StavrosK
This says versioning in the URI is wrong. Why? I much prefer separating my API
versions into different files at the dispatcher level. Doing it with the
header would be a mess in most frameworks, and I don't see what it hurts.

Also, what about custom HTTP verbs? Many times I need something more than
GET/PUT/POST/DELETE. What happens then? I haven't seen anyone talk about that.

~~~
almost
With a RESTful API you don't tend to need IDs most of the time, you just use
URLs. So having all the versioning info in the URL is not so great, you change
the version and suddenly all the URLs aren't valid anymore.

But more important that is upgrading a version on an API may not be an all or
nothing thing. You might want to start using the new features of the API on
one resource type but you aren't ready to upgrade your usage on everything
else. If the version is in the API you'll have to take apart and put back
together urls to get the right ones, this is logic you don't want to have to
encode into your client. If on the other hand you use Accept headers to do
versioning you can have as fine grained control as you need.

Regarding the custom HTTP verbs it may seem like you need those at first but
in practice you really don't and there is almost always a good clean way of
doing things that doesn't break anything (or so I've found). I find that the
solution is usually to introduce another resource or two, the transactions
example from the article is a perfect example of this.

I know it sometimes seems like this is all abstract stuff that has no impact
on the real world but it does make sense eventually! It's really lovely to use
a properly RESTful API :)

~~~
nirvdrum
Huh? The whole point of having a version in the URL is so you can roll out a
new set of URLs and their corresponding endpoints without touching the old
ones. When v2 of the API comes out, you still support v1. That's no different
than using headers. If you sunset or change an API call, the header isn't
going to save you any trouble. In fact, since the client now won't get a 404,
but rather something else, the cost of debugging goes up pretty substantially.

~~~
almost
But how do you deal with the partial upgrade scenario? I might want to use a
few of the new features in my client code but not have the time to upgrade
(and test!) everything just yet.

Of course version numbers in URLs can have their place too. But I think they
should only really be used in situations where you have upgraded so much that
the original URL space just makes no sense. And if you can avoid huge breaking
upgrades like that through good initial design then all the better :)

~~~
nirvdrum
The same way you'd handle it on a per-header basis . . . you just use the new
API version in the URL where needed. Sorry, I feel like I must be missing
something here.

~~~
almost
You are a little. In a properly RESTful API you simply don't construct URLs
most of the time. Instead you follow links. If you change the URL structure
you break the links. If that's what you want then a version number in the URL
makes sense, but in a properly RESTful API that's probably not what you want.

I think for a lot of people the reason they don't see the benefit of things
from REST is they try to use them in isolation. You say "this is useless for
my RPC style API!" and you are right.

~~~
nirvdrum
But, if you follow a link and that link is generated by the server, I still
don't see how encoding a version number in the URL makes things any harder.

FWIW, I've made an effort to follow the purity of it, but the APIs I see that
try to do true ReST are insanely obtuse. If you know of any real world case
studies where a provider went from "fake" ReST to true ReST, I'd love to read
it. The contrived examples are not helping me out in the comprehension
department.

------
tzaman
Interesting. But it has one flaw; how exactly would I do this

curl <https://api.twilio.com/2010-04-01/Accounts> -H "Accept: application/json

inside a browser on a normal GET request?

~~~
o1iver
Why would you want to do that from a browser?

~~~
crazygringo
Ummm... why _wouldn't_ you? Rich web clients and all that?

~~~
o1iver
I thought he meant doing it manually. Using XHR is trivial isn't it?

------
hcarvalhoalves
A lot of good points there, but the part about detecting mobile devices is a
bit short sighted.

Varying your content based on mobile User-Agent (or any User-Agent actually)
renders public caches almost impossible to get right.

~~~
lhnz
>> Varying your content based on mobile User-Agent (or any User-Agent
actually) renders public caches almost impossible to get right.

Interesting. What would you recommend doing instead, supposing, for example,
that you are meant to be returning a different set of items depending on a
device identifier, and that you have to support 100s of devices? Should this
be considered a different resource instead of a different representation?

Also, can you point me to a nice resource about public caches?

Thanks!

~~~
hcarvalhoalves
At your cache layer (e.g. Varnish), you would need some VCL to collapse all
the hundreds of User-Agents options into something sane like "X-Device", feed
this header to your backend, and vary the content based on that instead. This
way you can cache just a few representations per resource (e.g., "Desktop",
"Mobile", "Tablet", etc.) instead of several hundred. The problem, of course,
is maintaing this list of User-Agents.

On his mobile example, it's much easier to simply be pragmatic and serve
content for different devices at differents URIs/domains altogether. It
doesn't break if you can follow some kind of convention, such that the URLs
from one map directly to the other (for instance, mysite.com/news/article ->
m.mysite.com/news/article) and then you issue redirects accordingly.

------
thomasbachem
Thanks so much for saying what needed to be said :)!

David Zülke has a very good talk about REST that he's holding at conferences
around the world regularly: [http://www.slideshare.net/Wombert/designing-http-
interfaces-...](http://www.slideshare.net/Wombert/designing-http-interfaces-
and-restful-web-services-phpday11-20110514).

~~~
drawkbox
Ah yes the conferences... When will the RMM (REST Maturity Model)
certification, books and classes be available? It will be the CMMI + SWEBOK
conferences all over again gangbusters! j/k. All good stuff it is just a good
portion of it is to sell books/conferences and sometimes the good engineering
parts are lost on the idea that in the end engineering is making things more
simple not more complex.

It is a good presentation and hits on many good points but also makes the REST
model a little too narrow for most client/consumer usage today easily.

------
___Calv_Dee___
This webinar by Brian Mulloy is a nice complement to the post and offers up
some great design tips when it comes to designing a RESTful API...

[http://blog.apigee.com/detail/slides_for_restful_api_design_...](http://blog.apigee.com/detail/slides_for_restful_api_design_second_edition_webinar/)

------
LewisCr
For more resources on this topic, I have been leafing through O'Reilly's
Hypermedia APIs book, it's been interesting.

~~~
vdm
<http://shop.oreilly.com/product/0636920020530.do>

------
latch
He didn't go over the common example of paging by including

    
    
       nav { prev: '...', next: '....'}
    

in the response. But, the thing that always concerns me about this is that it
requires the client to maintain state. If you consume such a web service in a
web app, and the user hits "next", you'll have to have stored the next url
somewhere.

~~~
icebraining
If you want to show any content to the user, you'll always need to hold it in
memory somewhere; that's inevitable. Storing an URL for an action is just part
of the rest.

Personally, I'd just use a closure and bind it immediately to the event
handler of the UI element.

------
javascriptlol
If I want to raise my blood pressure into the 180's all I have to do is open a
thread about web design "principles".

He has the perfect anti-example for HATEOAS right in there: financial
transactions. You would never in 1 million years want to discover the API for
such a thing by experimentation, because there are specific precision
requirements.

Every time someone tries to explain the benefits of this nonsense to me it's
either 1) something you could already do with sockets 20+ years ago, or 2) a
poorly motivated academic idea that doesn't get me closer to implementing a
correct system with good documentation.

