7 ms·
Nobody Understands REST or HTTP
- glenjamin 15y agoIs there any way to make the browser do an Accept: application/csv header on a hyperlink? I'm pretty sure users like their "Download as CSV" links, which I've generally done as /normal/resource/url(.csv) While this post sets out the ideals, I think there are some cases where for usability, you have to do something less than ideal.
- Roritharr 15y agogood point, as long as the browsers don't have convenient way of displaying you the possible displayable mime-types this function isn't very useful to the enduser.
- ianterrell 15y agoThey're ivory tower ideals. The web has grown organically and it has the warts to prove it. It's useful to think about the spec and to work toward improvements, but if it's real world possible to have your services work well for mobile clients on m.domain.com and real world impractical to do so on your main domain (or any of the other examples regarding actions, languages, versioning, whatever)—then by all means, break the rules.
- icebraining 15y agoI think his main problem with the m.domain.com was redirecting to the main page. If it did a 303 See Other to the mobile version of the same article it wouldn't break the spec, as far as I can understand it.
- justincormack 15y agoIf you do use content type negotation, you are best off giving each type a different url (with the conneg doing a redirect) if the representations are usefully different ie you might want to bookmark one or the other. In practise no one does use it, so just forget about it.
- config_yml 15y agoLooking at the newer spec, we should be able to use "hreftype" for content type or "hreflang" for accept language: http://www.w3.org/TR/xhtml2/mod-hyperAttributes.html#s_hyperAttributesmodule http://www.w3.org/TR/xhtml2/mod-hyperAttributes.html#s_hyper... I don't know if any browser will implement this or has implemented it, but in real world scenarios we'll probably have to stick with .csv and en/foo or ?locale=en for a couple of years...
- pavpanchekha 15y agoXHTML2 is never coming. That train has left its station with HTML5. So long, elegance and ideals! At least I have my ruddy practicality here.
- deleted 15y ago[deleted]
- icebraining 15y agoXHTML2 is dead, but the current HTML5 spec includes a 'type' attribute: http://www.w3.org/TR/html5/links.html#attr-hyperlink-type http://www.w3.org/TR/html5/links.html#attr-hyperlink-type
- marcinw 15y agoAccept header is all but useless these days. Servers rarely look at the Accept header that is sent with the request, and browsers can rarely know ahead of time what type of content to expect when merely clicking on a URL. Check out this blog post by Eric Law on IE and the Accept Header (http://blogs.msdn.com/b/ieinternals/archive/2009/07/01/ie-and-the-accept-header.aspx http://blogs.msdn.com/b/ieinternals/archive/2009/07/01/ie-an...)
- icebraining 15y agoIt depends on whether you're doing a normal website or if it's (also?) a webservice. There are more HTTP clients besides browsers.
- masklinn 15y ago> Is there any way to make the browser do an Accept: application/csv header on a hyperlink? Sadly no. Browsers suck ungodly amounts of dicks in their handling (or absence thereof) of the Accept header. I don't know of any web browser with an even remotely useful behavior on that one.
- ericflo 15y agoThe problem with posts like these is that they say things like "THIS IS BAD!!!!!1" without saying why.
- ianterrell 15y agoThat's not true with this post in particular. It's not saying various practices are "bad," but that they don't conform to REST or the principles laid out in the HTTP specs.
- ericflo 15y agoThe above quote "THIS IS BAD!!!!!1" was lifted directly from the article.
- ianterrell 15y agoBefore he even discusses his individual points the author gives his definition of "bad," and the reason the other approaches are "bad." From the introduction: > Let's talk about a few cases where either REST or HTTP (which is clearly RESTful in its design) solves a common web development problem. > so they make up a partial solution that solves their given case but doesn't jive well with the way that everything else works
- icebraining 15y agoThe problem is if you don't follow those constraints, but still call your system REST. The meaning of the concept is rendered useless by so many people abusing it without understanding what it means.
- strmpnk 15y agoI've personally given up trying to save the term REST. It was hijacked and will never recover completely at this point. What I've been looking for is a good alternative name. Sometimes I'll write out representational state transfer which is clever enough to get past most REST pretenders but I have yet to find something short.
- strmpnk 15y agoI guess I should clarify my statement. The article is right on the dot. The point here is that arguments like this really need a new label. That's all I'll say.
- lazylland 15y agoBut I didn't think that he used the terms too loosely. What do you think was lacking/superflous in his arguments ?
- strmpnk 15y agoI meant this to apply in general. Rather than try to correct people we should introduce people into the architectural style and since REST already means something to many, it only seeds confusion.
- jballanc 15y agoVery good read, and thorough. I particularly like the transaction example. It seems like a common idiom that trips people up with REST. However, I do have a problem with REST that I've been dealing with lately. Specifically, the question of web-hooks. Many services today allow you to pass a URL that they will hit with a POST request whenever something happens. A good example is the GitHub post-receive hook (http://help.github.com/post-receive-hooks/ http://help.github.com/post-receive-hooks/). So, to be a good student of REST, I create an /update resource for the POST (similar to the /transaction example from the article). However, /updates might come in a variety of formats. Not just JSON vs XML, but GitHub vs Gitorious vs Beanstalk vs etc. So, how do I handle these "formats". Presumably the "Accept" header is out of the question (unless the provider happened to know about MIME's vendor extensions and used them). So then is it acceptable to add a parameter? Use "/update?from=GitHub" for example? Or, is it appropriate to use an extra path element like "/update/GitHub", since the resource really is a "GitHub update", not just a vanilla "update"?
- ianterrell 15y agoThere's no right answer, but it's helpful to think about it from a data modeling point of view. If where the update comes from would be stored as an attribute (i.e. column in the table), use the parameter option (/update?from=GitHub). If, however, they'd be separate types of updates (i.e. separate tables), use the separate URIs (/update/github or /github_update). This is an analogy, of course, as there's no need for a 1-to-1 resource-persistance mapping, but it's a useful way of thinking about it, I think.
- icebraining 15y agoI don't see what's the problem. Github is the client, so they POST to you the data, so they should include a 'Content-Type' header with the format of such data. Then you can process it accordingly.
- ericmoritz 15y agoWhat I've seen in the past (mainly from Pylons) is to have an extension on the end of the URL so: /updates/ has a default format say XML and then there's a JSON resource called /updates.json, /updates.txt, etc. Keep in mind what the R in REST stands for. Each resource is a representation of internal data. You can have multiple representations under different URLs even though they're powered by the same internal data structure. Ideally you'd use the Accept header to do it but sometimes you need to be practical.
- Sidnicious 15y agoI had a really interesting conversation about this with a coworker a few weeks ago. We were talking about URL design. I argued for URLs like this: /networks/ /networks/girl_talk/ /networks/girl_talk/tracks/ /search?term=bass&sort=artist He argued for URLs like this (note the pluralization): /networks/ /network/girl_talk/ /network/girl_talk/tracks/ /search/bass/sort/artist/ My case boiled down to, “A URL represents the path to a resource. You should be able to remove any number of parts from the end of a URL and be left with a different, meaningful URL. In the case of search, the terms are options that describe what you want returned by the search, not resources.” His case boiled down to, “A URL is a sentence. You should be able to read a URL as English and get a good idea of what it represents. In the case of search, adding more path components adds words to the sentence to make the search more specific.” He pointed out (paraphrasing) that URLs are a language — and languages evolve. URLs as paths better embodies the RFC, but a new style of URL might be more meaningful on today’s (and tomorrow’s) web.
- smiler 15y agoEither way I don't think it matters. Just get it done. Clients do not care about URL structure, they just want their problem solved. I redid an app and prettified the urls (yes I know this is slightly off topic) and no one has commented on it. Developers will use either, just do it and provide documentation and be done with it
- espeed 15y agoThis is the same position Mark Nottingham (http://www.mnot.net/personal/ http://www.mnot.net/personal/) takes and expresses in his talk "Leveraging the Web for Services at Yahoo!"(http://www.infoq.com/presentations/services-without-soap-yahoo http://www.infoq.com/presentations/services-without-soap-yah...). However, Mark created a service called "Is It RESTful?" (http://isitrestful.com/ http://isitrestful.com/) to deal with all the engineers asking him that question :)
- kenjackson 15y agoExactly. REST is interesting, but understand why its interesting. If you're doing it because its a popular buzzword, that's just cargo cult. It's good to know about REST so you can use it where it makes sense. But at the end of the day, doing what is right for your app trumps following any given methodology.
- archgoon 15y agoI don't think that I can fully agree with the idea that a news article written in English is not different content from the German version.
- icebraining 15y agoMaybe not a news article. But for example, if you're seeing a user's profile with the UI in English, is it really a different resource that the same user's profile in German? I don't think it is.
- bergie 15y agoTechnology-puristic take on this is that both the English and the German versions are just representations of the 'real' story underneath. Generally works better for more real entities like for example specific products, than for articles.
- palves 15y agoWhile I generally agree with the principles underlined in the article, using the Accept-Language header is definitely not the right way to control internationalization. Remember that one of the advantages of URLs is the ability to easily share them, however I'm not sure I'd be comfortable sharing content that could show up translated to some recipients, based on the language of their browser/application/computer. For example, most CMS systems assume that the content can be completely different between languages (for the same article): you can have the full text in English and only a teaser in other languages. Maybe not a pure REST approach but using '/en','/pt','/fr' in the URL has proven to be much easier and safer, from my experience.
- icebraining 15y agoIt depends on what content is translated. I think that Accept-Language is OK for UI elements - seeing 'entrar' instead of 'log in' and elements like that. For actual content, probably not.
- mdiamond 15y agoThe part about using "Accept" headers instead of "/v1/" links really threw me for a loop. The APIs I've come across from major applications (e.g. Twitter, Foursquare, Instagram) all have versioning in the link structure, not in the "Accept" headers. I understand that this post is supposed to highlight what REST APIs should do, not what everyone should do, but the author's emphatic insistence that "THIS IS BAD!!!!!1" leaves me confused as to what the proper method is.
- decklin 15y agoI don't understand the point of "uri":"/transactions/1". Isn't the new resource's URI already part of the response (in the Location: header)? It's sort of like saying GET /posts/show/1 vs. GET /posts/1.
- icebraining 15y agoI agree, it's redundant.
- stanleydrew 15y agoIt's redundant in that particular instance. But it's a representation of a resource. It might be nice to define the representation across your entire system so that when you grab a transaction resource with a GET later, it still has that URI in it. Or maybe not. But it's not obvious that this is a bad idea.
- icebraining 15y agoBut to access that JSON document with the URI, you had to know the URI already (in this case, by following the Location header). It's like having a link on a webpage to itself, what's the point? I can just refresh.
- iandanforth 15y agoThis is an excellent example of a spec being deemed more important than a useable system. Frankly, I don't give a damn about the REST spec, and neither should you. When I see an API I want it to be simple and clear. /getAllPages/ Hey, it's a verb and I've got a pretty good idea of what I'm going to get back /getAllPageNames/returnType/JSON Now I really know what I'm getting. The simplicity and usability of this structure absolutely trumps a spec compliant call that involves request headers and nouns. If you're building a system that requires having read someones dissertation, you're not doing us any favors. Especially when it comes to an API. Keep it simple, stupid. Remember that your understanding of what a URL 'is' or 'should be' comes from a great deal of technical experience. If you're not working day in and day out to make powerful tools accessible to people WITHOUT such experience, please stop programming. Really, get out of the pool. Whatever awesome knowledge you need to make a system work internally is invaluable, but your interfaces should make the world a simpler, more magical place.
- binarymax 15y agoDid you read the article? No matter nouns or verbs but in your example you are doing an HTTP GET. Does get getallpages sound right to you? I did not downvote you but the REST architecture is well thought out, simple to follow, and very sufficient if you are moving content over HTTP.
- iandanforth 15y agoFirst off, thanks for taking the time to reply to my admittedly baiting post. I do have a serious point I'm making though. Lets walk through it. http://www.mywebsite.com/api/getAllPageNames/returnType/JSON http://www.mywebsite.com/api/getAllPageNames/returnType/JSON In this string 'get' appears once. However, as an experienced dev, you know that this is a GET request. To you it looks redundant. However to someone trying to understand what will happen when they hit enter with this URL in their location bar it is meaningful. The question at that point is naturally "But if you don't know that's a GET request then why are you using an API?" This is the point I'm driving at. There are scores of underserved individuals who want to do interesting things with your website that go beyond your GUI, and they are just brave enough to read through your API docs. Now, when I'm thinking about API design I have a big initial choice. Is this API for skilled developers who care about the REST spec? Or is this a tool for as many people as possible to get more out of my service than I have time to accommodate with features. This is where I will always say "I don't care about the spec." A really talented dev will read the docs, discover how my design works, and will write something cool on top of it. I can trust the hackers I know to make things work by hook or by crook. The same cannot be said for someone who really wants to extend my functionality but isn't a talented developer. I feel it's my responsibility to produce a tool that can be used by as many people as possible. I don't want to make a high-end professional camera, I want to make a better point and shoot. I want to extend the abilities of people, not demand they gain a large skillset to use my new tool. New programmers and enthusiastic users are always on my mind. These are the people who's preconceptions are that it should 'just work' and that if it doesn't it's my fault. This is why I applaud decisions like Chrome dropping http:// http:// It simply doesn't matter to 99% of the users of the product, and in fact makes browsers less friendly and more confusing. If I can get my api to work like this, then I will: 'I want to see all the names of pages on mywebsite.com' If I had access to a deterministic natural language parser then I'd use it. As such a thing doesn't yet exist, I try to remain as true to that ideal as possible. The REST architecture may be less confusing than others, but it is far from simple.
- heyrhett 15y agoHe's right, but older web developers might remember the alternative, which was having no design pattern at all. Most web developers aren't going to read the computer science papers about REST, and how strictly you want to adhere to it, depends on you, and your development team. It's a design pattern, or a tool, but it's not a religion. On that note, I've gone into several job interviews where they ask me to explain what REST is, and I always start with, "REST stands for Representational State Transfer...", at which point, I get the feeling that the interviewer wasn't aware of that, and I wind up telling them way more about REST than I think they wanted to know.
- binarymax 15y agoThis is a great article. One challenge I am facing now is both building a RESTful API, along with a UI that uses the API. The biggest question I have is the use of shebangs in urls with the ajaxy app. We must support IE so pushState is out, but shebang just seems like a hack. I think at this point I have no choice but to implement shebang but I wonder if there are any viable alternatives?
- deleted 15y ago[deleted]
- brendoncrawford 15y agoThe title seems rather sensational. Is that really necessary?
- brendoncrawford 15y agoWhy all the downvotes? Is it really true that NOBODY understands REST or HTTP?
- lazylland 15y agoHere's something I've observed: i) most successful "RESTful" APIs don't really follow all the REST principles (e.g Flickr, Amazon, Dropbox). My thumb rule is this: If an API does not start from a "mother" URI that gives you the most updated list of resources that can then be requested by the application, it is not really HATEOAS. ii) a purely resource-oriented view of your entire API space shoehorns you into doing really strange things to keep REST "purity" So my conclusion is that using an architecture/concept originally intended for humans navigating hypermedia documents may not be a natural fit for parts of your API that cannot be modeled as such. See the Dropbox REST API documentation (http://www.dropbox.com/developers/docs#api-specification http://www.dropbox.com/developers/docs#api-specification) (" Section: Deviations From Standard REST Style") to see an example of the pragmatic decisions taken.
- dreamdu5t 15y agoREST is great and all, but browsers don't allow it. The only thing you can do is GET, nothing else is supported cross-domain. No matter your thoughts on REST, it's dead. It's never happening. This argument has gone nowhere for 10 years. Very few if any websites conform to the spec, and browsers have made it impossible to do so.
- clintjhill 15y agoContent Negotiation is a critical part of REST APIs and it's my observation that most simply ignore or default to JSON in all cases. Good REST APIs allow the client to "choose" the mime type. Without this part of REST - you have no "representational". On that topic, to rely on an 'Accept' header is pretty risky. That presumes the client will always have control over the headers. It is in my opinion always wiser to make the API determine mime type by extension (.html, .xml, .json etc).
- clintjhill 15y agoWas there something particularly wrong about my comment(s) here? Seems I was down voted on all 3.
- mberning 15y agoI really dislike creating resources to represent transient actions. Not a big deal in the case of a bank transaction as that is something you could easily imagine needing to be stored for later retrieval. A different example is relating one social network friend to another or searching for specific people on the site. Those are things that, to me, are much more borderline and I would err on the side of not representing them as resources.
- stanleydrew 15y agoYou haven't really explained why you don't like creating resources to represent transient actions. What's wrong with POSTing to /friend-requests with requestor=stanleydrew&requestee=mberning? There's no need to keep a log around if you don't have use for it.
- bradgessler 15y agoThe biggest problem with today's REST implementations is that they're essentially a database serialization layer. Consider how a RESTful Rails model is typically represented as: { book: { id:1, name:"To Kill a Mocking Bird", author_id:2 } } How do you get more info on the author if you only have this piece of information? Rails/ActiveResource guesses through convention: "/authors/2", but that might not be the case, which makes this approach very brittle. A better more "RESTful" approach might be: { book: { href:"/books/1", name:"To Kill a Mocking Bird", author: { href:"/authors/2" } } } The REST client would then be able to traverse the representation without making guesses at the URL, and if the end-point of '/authors:id' changes for whatever reason, the href would be updated accordingly. Pagination/large data-sets could be solved as well: { books: [ href:"/books/1", name:"To Kill a Mocking Bird", author: { href:"/authors/2" } } ], rel: { prev: "/books?page=1", next:"/books?page=3" } } ... and a bajillion other common RESTful API problems through better convention. I'd agree with the author that REST is misunderstood, but my opinion is that its misunderstood on the grounds that today's "REST" implementations are lame database serializations. The web has been doing this since the <a href/> tag was conceived, but for some reason, modern REST implementations left this out.
- clintjhill 15y agoYou may find that Sling supports you're request here. But to the extent that they are all "lame database serialization" layers, I'd have to say "well - ya". REST is kind of just that. I think that what you're really trying to say is that implementations you have found don't do HATEOAS.
- bradgessler 15y agoI disagree that "REST is just kinda that [database serialization]"; it is one approach to REST, but its brittle and tends to bias developers towards over-engineering their API into these tiny little pieces that correspond with each database table or model. I'm designing the API for Poll Everywhere right now. Internally a multiple choice poll resource consists of several database tables and Rails models, but I simplified the externally facing JSON representation down to: { multiple_choice_poll: { title: "Fav color?", options: ["Red", "Blue", "Green"], sms_enabled: true } } Had I followed Rails REST conventions, I'd have an overly complicated chunk of JSON. I'd love to implement a full HATEOAS stack on Ruby/Rails; we'll see if I get around to it. --- BTW In case anybody needs to Google HATEOAS (like I did): http://en.wikipedia.org/wiki/HATEOAS http://en.wikipedia.org/wiki/HATEOAS
- rubyrescue 15y agogood article but...he says version numbers in the url are bad but doesn't say why. using accept headers for versioning is a hassle for every client and makes browser based testing much more difficult. also a v1 user really might not be the same as a v2 user so they shouldn't be the same resource.
- notJim 15y agoYou keep your practical considerations away from this man's ivory tower!
- icebraining 15y ago>he says version numbers in the url are bad but doesn't say why. Because according to the spec, each resource is named by a single URL, so two URLs name two different resources. But if you put version numbers in the URL, you might end up with http://example.org/v1/rubyrescue http://example.org/v1/rubyrescue and http://example.org/v2/rubyrescue http://example.org/v2/rubyrescue, which according to the spec are two different users but in reality they're the same. >also a v1 user really might not be the same as a v2 user In what cases should the users be tied to the API version? I can't think of any.
- rubyrescue 15y agogood point, but the point of a restful resource is that the url represents a resource, but then w/accept header versioning, i now need two pieces of data, one of which isn't visible, to properly represent and retrieve a resource. I guess my point is that if i have to pick, i'd rather occasionally have two request urls with a minor version difference that are actually the same resource than two urls that appear to be the same resource but are not because one was requested with a header that affects the returned data.
- icebraining 15y agoYou're confusing resource with representation. An URL is a resource, but if the representation of that is a JSON document or a picture of him/her, that's up to the server. Just because an header affects the representation of a resource, doesn't mean they're different resources.
- mainguy 15y agoI've had this discussion about hundred times now. REST "standards" are as important and significant as brace indentation "standards". A big problem with REST is that it is NOT a canonical (or even important) standard, but rather a useful pattern than can be used to make things exposed via HTTP more intuitive. The evil side effect of this is that a metric crapton of architects/engineers are wasting fifty bajillion programming-hours arguing irrelevant details about who's doing it "right" instead of building useful software. You cannot do REST "wrong" and more than you can do software "wrong"... Folks who argue about the "right" way of doing software are usually "wrong" because they are focused on writing software instead of solving problems. We need to keep our priorities straight.
- stanleydrew 15y agoI understand your frustration but I think you are misguided. Standards (and their cousins, best practices) are important to think about in order to create diverse yet maintainable and inter-operable systems. "A big problem with REST is that it is NOT a canonical (or even important) standard, but rather a useful pattern than can be used to make things exposed via HTTP more intuitive." No, its not meant to make HTTP interfaces "more intuitive". HTTP clients are machines. They don't have intuition. When your web browser hits the HN front page, it isn't using intuition to figure out what links to display. You can make an argument that for a particular web service, adhering to a particular principle of REST doesn't matter. But you have suggested that the principles of rest never need to be an important consideration for any web service, which I submit is plainly false.
- wyuenho 15y agoI read the post and I have to say that he's got a nice flamebait title but totally avoided the thorny issues that people argue about. In fact, I'd like to be pointed to a solution for the following problems: 1. I'm an old Web programmer, and my introduction to the Web started with HTML, not HTTP. I don't just write APIs, I write Web apps. I find it difficult to explain to people what this means: <form action="/some/noun" method="POST"> If you are religiously RESTful, you probably think this is fine. But I'm a religious English reader. When I see the word "action", I think of a verb, not a noun. When I see the word "method", I think of "how", not "what". So when I look at the HTTP spec, all the HTTP "verb"s look to me like how-I-should-do-something, instead of what-to-do, and the resources (URLs) look to me like the what-to-do, instead of what-they-represent. Small semantics issues I suppose, but here's another one: 2. HTTP is not a programming language, and yet it demands a (very) finite set of actions and an infinite set of objects to model the real world, where there are an infinite number of actions and objects. What I mean is, in Java or whatever OOP language, I can define classes to model objects and define methods in classes to model actions on objects, but I'm not sure if I can do it pragmatically in HTTP without getting yelled at. 3. HTTP statuses. Almost the same problem as the above. I have many different kinds of statuses, not all of them fit in the finite set of HTTP statuses, and they don't always provide the granularity I want. Can I return a non-standard status number? How would the clients behave? I have no idea. 4. Being RESTful means not being stateful. But you see, there's this thing called session and login cookies and many other tracking cookies that I have to take care of. Again, I don't just write APIs, I write Web apps. I would like to not do multiple handshake requests just because a paper says I should. I would also like to not get yelled at when I decide not to. 5. HTTP is RESTful, thus HTTP is REST. Please don't tell me HTTP is the best we can do. Can I have something more minimalist, extensible and powerful enough to model the real world? -- A troubled Web dev.
- noduerme 15y agoIt's actually kind of lame that this pompous flamebait makes it to the top of HN, and then he concludes his post saying he doesn't take comments on his blog. excusez-moi, what is he the New Yorker? I'd prefer to address his pomposity on his own turf rather than here, so all I'm going to say is this has all been said before, and it's a bitter irony to spend time talking about flogging dead horses while debating the semantics of a meaningless buzzword with nobody but yourself.
- latch 15y agoIt really is a good read, I need to digest it, but my initial reaction is that some of this isn't pragmatic. Versions in URLs makes for dead-simple routing in any framework. Also, many APIs are used in a way where you know consumers will create a resource without requesting it (or at least, not within the same session). So why return any location information (whether in a header or in the body)?
- Stormbringer 15y agoRest was a really big deal in the Java web-app world for about a year... It was back when early versions of Struts were 'the designated alternative', and in the bad old days of J2EE and JAX-RPC. Then Java EE 5 came out, which solved large chunks of the pain that J2EE inflicted, JAX-RPC got replaced with the infinitely better JAX-WS and there was a new breed of web frameworks as well, which blew Struts out of the water. About that time REST essentially became 'yesterdays technology, solving yesterdays problems'. I find it interesting that the guy banging the REST drum is a Ruby fan. Has REST always been part of Rails? Or is it something that has crept in over the last couple of years? Is there anything genuinely new here, or is it the same old story, some dude clinging desperately to an obsolete technology?
- CeiII 15y agoWhere to start with a comment like this? '...REST always been a part of rails?' '...obsolete technology' How is REST -- a set of architectural principles and constraints -- obsolete when you use it every time you browse to a web page? I feel people need to start treating REST more for what it is rather than an API or some library, or SOAP for that matter.
- mudetroit 15y agoI want to know what part of the Java web world you are talking about exactly? I just question the concept that REST is in anyway considered to be obsolete within the Java web world. Spring-MVC focuses more and more around this technology, and is also the delivery point for REST web services from spring; Struts 2 has slowly moved more towards RESTfulness; and additionally frameworks like Play have come around.
- ams6110 15y agoI've been working with/learning about Webmachine lately. A really nice framework for building REST APIs.
- maurycy 15y agoA very good and comprehensive writing. One thing that I cannot find mentioned neither in the article nor in comments, is the confusion related to the idea of state. While REST is, by definition, stateless, it merely describes the session, not the manipulated data. There's no way to avoid, at least implicit, object's state. For example, if user's password is not empty, it means that the user already set the password. More comprehensively, with /users/1/edit, or whatever, it is frequently expected to get a different validation error, depending on the flow, such as a paid account might require more billing related details than one without email confirmed. Of course, it is a nightmare to maintain such matters implicitly. That's why Ruby on Rails plugins like acts_as_machine, and similar, come handy. They do provide an explicit description of the object's behaviour, easy to transform into documentation, depending on the current state. The idea shows its full potential with multipage forms. Each step of the form might be described with a different state, stored in the state attribute, leaving the controller RESTful, and the model's validations easy to understand. A yet another confusion comes with too close database mapping. To stick with Ruby on Rails, there is nothing preventing the developer from creating his own setters and getters, like def vattr=(); end; def vattrr(); end. The framework passes the value of a virtual attribute, using params, to #update_attribute, and other methods, the same way it does for regular attributes created automatically from the database's schema. Very frequently such attribute provides a much cleaner way to represent the model, rendering either the HTML or the API much more easier to write or understand.
- deleted 15y ago[deleted]
- rkalla 15y agoI thought I finally had REST figured out until I read this. Does anyone else see a diminishing return on pedantically following the REST-prescribed design and actually creating an API that people are familiar with out of the gate? I feel like if I followed this article to the T in my current design, anyone trying to integrate with it would spend so much time reading my API documentation just to figure out why they weren't getting an XML reply that it would stop being productive. I am working on an API for imgscalr right now and I think I have it about 80% RESTful at the moment -- the parts I'm not doing is paying any attention to the headers either coming or going between client or server. I'm using the more recent "classic" /path/object.{format}?arguments format that I have seen folks like Wordnik and Vimeo use. It may not be purely RESTful, but it is intuitive and I can't help but think: "Remember 3-4 years ago when REST wasn't all the craze and no one knew what it was? The web still managed to function back then..." I'm trying to mix some practicality in a bowl filled with "best practices" and come up with something that most people can stomach. I hope I hit that mark, but we'll see. As far as I'm concerned I'm sticking with the versioned URLs because I find it more intuitive for endpoints that change, get renamed or are removed than slamming one inside of a mime type or header or even a query string param a la AWS.
- Vitaly 15y agousing object.format is perfectly ok regarding the rest. using headers might be more pure, but its not the biggest issue. the biggest issue with the rest-wanna-be interfaces is their use of object ids instead of object uris. so that I have to construct my own urls to access stuff. in a proper restful api you are NEVER supposed to construct your own url. you are supposed to get all the relevant ones from the service. and this kind of api is actually much more user friendly and allows for much better discovery. you just get the single top api url which has references for all the available collections objects and operations right there in the result.
- rkalla 15y agoVitaly, So something like: GET /image.json/pig.png?size=150x100 as opposed to GET /image.json?id=pig.png&size=150x100 where the arguments specific to the noun (or object/entity or image resource in this specific case) go in the query string, but the URL stem itself must be a valid resource reference?
- comex 15y agoSome of this feels like trying too hard to adhere to HTTP. For example, > Accept: application/vnd.steveklabnik-v2+json This declaration loses information, because it no longer contains the MIME type for JSON in a standardized format. Assuming the server responds with the same string for Content-Type, any application that does not know specifically about this API can no longer recognize that it's JSON and, e.g., pretty-print it for a user, as I haven't seen done for JSON but is regularly done for XML by browsers. On the other hand, the original suggestion: > Accept: application/json works in theory, but in practice makes it more difficult to test the API in a browser. This is not the end of the world, but there does not seem to be any real benefit in using Accept. I cannot think of any practical situation where a tool can use the standardized header for an advantage...
- rhu86 15y agoHaving your clients send an application specific MIME type can actually be better for browsers as well. All you need to do is provide a representation of your resource in HTML which browsers will request by using "text/html" in the Accept header. I've found this a nice addition to documentation and, depending on how well the HTML representation has been done, is great for learning/exploring an API.
- wanderr 15y agoIf nobody understands REST, and as other articles have claimed, nobody does it right, then why do we keep trying to use it? Switch to something simple that everyone can understand like JSON-RPC and quit worrying about pedantry.
- deleted 15y ago[deleted]
- ghostwords 15y agoIronic that the author's homepage (http://steveklabnik.com/ http://steveklabnik.com/) is a confusing pretend console that takes several seconds (on every visit!) to reveal useful information.
- thedebuggr 15y agoExcellent article... We followed all of these Rest principals when we designed apis for HP cloud print (i think it will soon become public)..except 1) Representing all resources with noun - We had a tough time representing all resources with Noun. One of our APIs is Post on \PrintJobs\ - creates a new print job But printing can only start when all the data (content to be printed) is uploaded on the server. So client needed an API to tell the server that it can start printing..something like this.. \printjobs\1\print \printjobs\1\cancel one way we thought to avoid this was to have a represent it job state and client can change them like this.. \printjobs\1 Put : <job> <state="print"> </job> But there are cons 1. These were not actually states, these were actions(verbs)..because state would be initialized, printing etc.. so if client does Get after making it Put..it will get "printing" not "Print". So we were tangling with keeping semantics clear and making it easy at the same time. Hence we went with these resources. Do you think it could modeled better? 2) When we think of versioning, we always assume that only the representation can be changed..why not behavior? Take for e.g. if api implementation changes but not representation..clients may be dependent upon the implementation (i know this is bad! since implementation details are getting leaked out from the API) Thoughts?
- extension 15y agoYou can't satisfy the HATEOAS constraint by simply returning URLs in the JSON response from your API. The structure of the data is still tightly coupled to your own application, and so must be any client that can make use of it. It is essential that RESTful applications be able to evolve independently from the client. To allow this, they must use forms of hypermedia generic enough to serve as the engine for all present and future versions of the application. If the client has any code specific to your app, then your app is not RESTful in any scope beyond its own. I'm not convinced that the whole resource vs action thing is all that important to REST. It's an ideal that has been largely ignored in practice and the web has been quite successful without it. Contrast this with HATEOAS which has been the unavoidable reality of the web since day one.