Hacker News new | past | comments | ask | show | jobs | submit login

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.




Yes. Hypermedia references are a requirement for something to be considered RESTful: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte....


The 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"


The 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.


It is back in discussion for html5, so may yet happen.


Upvoted 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. :)


I 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.


Perhaps something along the lines of the following would provide a good balance 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.


Oh 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...

Looks perfect.


The 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.


You 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.


I 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


I'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.


Do you have any bits of this code open sourced?


I 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.


You 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.


Pagination is implicitly non-restful as page=X can change anytime a new book is added, depending on the ordering getting done.


Roy 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...


That'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.


If 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.




Applications are open for YC Summer 2019

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

Search: