5 ms·
The biggest problem with today's REST implementations is that they're essentially a database serialization layer. Consider how a RESTful Rails model is typicall
by bradgessler 15y ago
The 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
- icebraining 15y agoYou would just have to include the URL where the client should POST the vote to (like with <form src=... in HTML pages) and it would be perfectly RESTful, imho. Of course, it would be better if there was a Standard Poll Format to avoid the proliferation of custom formats that reduce code reuse, but alas, I don't think there is.
- clintjhill 15y agoI realize I implied "every table or model", and I would always argue for composition the way you describe it. But ... there are good reasons to decompose and expose these things in your API. While maybe not for Public consumption but certainly for Private. It's my opinion that the way REST beats SOAP in the enterprise is that in almost all cases it's much quicker to build decomposed services. And then likewise composition of said services is also much easier.
- awj 15y agoI've ended up doing without ActiveRecord's to_xml/to_json to (among other things) accomplish HATEOAS within Rails. Instead I'm using xml builder and a roughly equivalent json-from-ruby-hashes template system. The process is a bit ugly at times, but so far the results have been pretty promising. We've already had api changes break enough internal clients that people are pretty excited about that never being their problem again. I could wish that Rails had a cleaner path and this regard, though. I've never understood the thought process behind Rails' serialization system. Why use MVC to deal with html and email but almost ditch it entirely for other document formats? Especially when we're dealing with something that could really benefit from embedded hyperlinks.
- bradgessler 15y agoDo you have any bits of this code open sourced?
- stanleydrew 15y agoYes. Hypermedia references are a requirement for something to be considered RESTful: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte....
- dreamdu5t 15y agoThe biggest problem? I'd say the biggest problem is browsers not fully implementing HTTP's REST support. Instead of having a different API for every freakin' website on the planet, we could use HTTP and actually implement GET, PUT, POST, DELETE. It's sad that it didn't happen in XHTML2, and also removed from HTML5.
- justincormack 15y agoIt is back in discussion for html5, so may yet happen.
- bphogan 15y agoUpvoted because I like your solution for pagination and for further information via an :href attribute. However, I don't see a real problem with the way Rails does things because it's "by default" and I think a dev ends up causing a lot of unnecessary trouble for himself by using stock to_json. The more I work with Rails building out a JSON API, the more I realize that .to_json is just another way to "scaffold" - it's not useful in production. :)
- awj 15y agoI can see that point ... but where's the direction on what to do next? What's the post-scaffold JSON mechanism? Bonus points if it lets me generate/embed urls with the knowledge/techniques I have from making web pages. If you say "erb", please don't be offended by me laughing.
- rbxbx 15y agoPerhaps something along the lines of the following would provide a good balance http://quickleft.com/blog/presenters-as-a-solution-to-asjson-woes-in-rails-apis http://quickleft.com/blog/presenters-as-a-solution-to-asjson... It's also worth noting that to_json should not be invoked directly these days in favor of as_json. It's now meant to more or less be an internal Rails API.
- bphogan 15y agoOh please ;) Don't hate on the ERb. It's fine for something like this. OK, I am only half-kidding. Have you seen RABL? I've been meaning to play with this. http://blog.dcxn.com/2011/06/22/rails-json-templates-through-rabl/ http://blog.dcxn.com/2011/06/22/rails-json-templates-through... Looks perfect.
- technoweenie 15y agoThe GitHub API uses the Link header for that. $ curl https://api.github.com/repos/github/gollum/issues -i HTTP/1.1 200 OK Content-Type: application/json Link: <https://api.github.com/repos/github/gollum/issues?page=2>; rel="next", <https://api.github.com/repos/github/gollum/issues?page=3>; rel="last"
- bad_user 15y agoPagination is implicitly non-restful as page=X can change anytime a new book is added, depending on the ordering getting done.
- bradgessler 15y agoThat's like saying that a resource is implicitly non-restful because its state might change. If a book is added, the page=x resource is simply outdated and should be refreshed.
- justincormack 15y agoIf you need page stability you can refer to the items at the top of the page not the page numbers, the nice thing about rest is they are still just next and prev links.
- pornel 15y agoRoy Fielding's paper says that "temporal services" are OK: > A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time. http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch...
- svv 15y agoThe RESTful way to solve such problems is not just by better conventions, but by conventions standardized by the appropriate media types. E.g., the REST service may define a Content-Type: application/vnd.acme-json-with-paged-hrefs that means that all "href" properties are URIs that may be paged by appending "?page=NNN" to them. If both server and the client understand this content-type, the representation may omit the "rel:" part from the parent example altogether. Constructing arbitrary URIs by the client is not RESTful; however in this case it's the server-side that is in control of URI generation mechanism (it could serve a different representation, with a different Content-Type:, if it chooses to) -- thus it's perfectly valid from the REST point of view. This is the same story as with the HTML <form> element. It also allows client to construct URIs by the specific rules known to both sides -- because the rules are defined by the appropriate standards about text/html.
- deleted 15y ago[deleted]