top | item 3635085

Nobody Understands REST or HTTP

100 points| shinvee | 14 years ago |blog.steveklabnik.com | reply

70 comments

order
[+] Argorak|14 years ago|reply
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|14 years ago|reply
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.
[+] richardlblair|14 years ago|reply
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|14 years ago|reply
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|14 years ago|reply
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 :)

[+] decadentcactus|14 years ago|reply
What I've come to realise is that if you try to make an API of any sort, somebody, somewhere, will write a post about how you're defiling the HTTP protocol.
[+] scott_w|14 years ago|reply
Custom verbs aren't really necessary. You can do some of your "method" naming in the URI. One example could be: /sum?number=1&number=2 which, when a GET is issued, will return a representation of 3.

If you need to perform some action that can be expected to take time, you can issue a POST request, which can give you a new resource that reports back on its current state. An example could be: POST /printer with the request body containing the document to print. It could assign a URI that tells you the status of the document (location in queue) and you can DELETE it if you no longer want to print the document.

[+] brown9-2|14 years ago|reply
It sounds like you are making an API design choice based on how easy it is for you to implement something internally. What about your client's ease?

Version in the URL requires them to update the URLs everywhere. Version in the accept header is likely a one line change somewhere.

[+] javascriptlol|14 years ago|reply
The problem is designing all this nonsense into the bottom layer in the first place. I've never heard a good argument as to why any of this is better than just starting with raw sockets for an app talking to a server.

Take HATEOAS for example; a completely academic waste of time. Writing a tiny bit of API documentation isn't hard. Caching is an awful thing to be designing in without knowing the specific application. Verbs are a hack bolted on to make hideous form/link driven applications work when the user reloads or moves back/forward.

[+] tzaman|14 years ago|reply
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?

[+] rue|14 years ago|reply
The short answer is that browser vendors need to get their act together. They've shirked this because no-one's demanded it.

Fortunately until they do, broadly, a browser user will always want the newest resource, and the type can usually be defaulted (you're using a browser, so you want HTML by default where available). Additionally, XHR and related technologies usually allow adding custom headers.

[+] richardlblair|14 years ago|reply
One way I have solved this issue is to look for the Accept header. If no valid formatting options are available in the Accept header look for a query string parameter.

To me this is vital. Being able to explore an api within an browser makes it exponentially easier to understand and use.

[+] o1iver|14 years ago|reply
Why would you want to do that from a browser?
[+] hcarvalhoalves|14 years ago|reply
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|14 years ago|reply
>> 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!

[+] thomasbachem|14 years ago|reply
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-....

[+] drawkbox|14 years ago|reply
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.

[+] latch|14 years ago|reply
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|14 years ago|reply
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.

[+] Argorak|14 years ago|reply
Isn't the whole point of REST/Hypermedia that the client holds the state instead of the server?
[+] javascriptlol|14 years ago|reply
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.