
Hypermedia APIs on Rails - AffableSpatula
http://blog.stateless.co/post/38378679843/hypermedia-apis-on-rails-why-dhh-should-give-a-fk
======
po
The convention that Django REST Framework (which is an add-on for Django, not
part of the core) uses is to add a 'url' attribute to each resource to
represent the cannonical id.

Even better, when you hit the API with a browser, you can click around and
explore the links easily:

<http://restframework.herokuapp.com/users/>

The docs talk about it a bit here:

[http://django-rest-framework.org/tutorial/5-relationships-
an...](http://django-rest-framework.org/tutorial/5-relationships-and-
hyperlinked-apis.html)

~~~
alecperkins
I like to take this one step further and return referenced objects with both
their ID and their URL as actual objects instead of strings. This is
incredibly helpful for working with the API in something like Backbone.js,
because then there's no need for logic in determining if it is getting a list
of IDs as strings or full objects. It's doubly helpful if the references are
to objects of different types. The client simply loads the objects as given,
and can do a sync if it's missing attributes it expects. (Of course, sending
the full data in one request is usually preferable.) Also, the `url` property
on the model just returns the `url` attribute instead of needing to duplicate
the URL construction pattern.

So,

    
    
        …
        {
            'id': 123,
            'url': '/resource/123'
        },
        …
    

instead of

    
    
        …
        '/resource/123',
        '/resource/124',
        …
    

or worse

    
    
        …
        123,
        124,
        …
    

Also, Django REST Framework is easily my favorite REST API tool for Django.
It's very straightforward to use just as much or just as little of it as
necessary. In fact, it's powering the main views of the upcoming second draft
of <http://marquee.by> (the entire site is effectively a browsable API).

------
binarymax
_...I came up with a simple media type that adds linking on top of JSON_

Adding hypermedia reflection to JSON does amazing things to APIs. We've been
doing this via oData for awhile, and it makes things so much easier on the
client. Anyone building a hypermedia/REST API with JSON (or XML) would make
good of using standard formats that incorporate this functionality and
attitude.

------
programminggeek
This doesn't need to be a Rails feature. Rails is for building web apps. There
is a whole bunch of extra stuff Rails does that a web api doesn't need to care
about. So, it really doesn't need to be a mvc web app framework feature.

Also, why tie this idea to Rails at all? Why not just make your own plugin or
Sinatra app or frameowrk or whatever?

~~~
AffableSpatula
Because rails is used for building APIs, linking is a good practice, and
there's no need to reinvent the linking/embedding wheel every time you create
an API.

Rails has API defaults which should include sensible linking defaults we can
build tooling around.

------
RTigger
I blogged about this same idea in response to a different article 3 months
ago. Seems like the hypermedia discussion keeps coming up. Here's my response
article: [http://rtigger.com/blog/2012/08/27/discovering-the-value-
in-...](http://rtigger.com/blog/2012/08/27/discovering-the-value-in-
discoverable-apis/)

TL;DR - there's no value in discoverable (hypermedia) APIs short of some
generic API browser that end users don't really want.

~~~
Ramone
There are a benefits, but most people won't notice them without first actually
using a hypermedia API.

* It's self-documenting. Client developers can find all the endpoints just by clicking around (instead of reading mountains of docs).

* Client apps don't need to keep a list of hard-coded urls for random access, removing one of the most brittle parts of client apps (they should know about rels of course, but those end up being easier to keep track of).

Once you actually use an API like this, other APIs feel like they're in the
stone age and how to do things with them seems like a continual guessing game.
And it's still simple as hell -- remember it's just json with links. It's not
like that requires a lot of extra effort.

~~~
RTigger
Fair enough - I haven't actually used a hypermedia API (short of OData). I
really can't see the documenting point though. Sure, you get a list of actions
that you can perform, but you get those in a response object. Some people
compare this to "intellisense documentation", but really it's more like having
to decompile the library to figure out what's going on. You have to do
something extra in order to figure out what the next step is, rather than just
having it available. Also, I'm pretty sure any API that is currently
"discoverable" probably also has a full suite of documentation. Why do the
same thing twice?

Not sure about other languages, but most of the client apps I make don't use
hardcoded urls - they use a base API url, and then modifications for specific
resources. The RestSharp library for C# is a great example of how this works,
and even in javascript it's not hard to refactor things so they use a base url
and append path & parameters based on the models you're working with.

I'm not arguing the simplicity of it, although it would be more simple to
implement if we agreed on a standard like in the original article. I'm just
arguing the value.

------
tlrobinson
Isn't this what the Link header is for? Why put them in the JSON?

The only reason I'm aware of is for compatibility with JSONP. Github's API
normally uses Link headers, but adds a "meta" object for JSONP requests:
<http://developer.github.com/v3/#json-p-callbacks>

------
lmm
For those of us not quite as embedded in the bubble as this author, what's
this in response to?

~~~
gamache
It's in response to Rails being on the trailing edge of Hypermedia/REST API
design, and not making moves to pull ahead. Rails's strength is in its sane
and powerful defaults; the absence of a sufficiently sane and powerful default
for API construction is a hindrance (especially now that ActiveResource is
getting booted from core Rails).

DHH has simply never taken REST/Hypermedia seriously as a design philosophy.
He, and Rails, have been content to move simple JSON serializations over the
wire and leave it at that. This was good enough a few years ago, but is
getting to the end of the runway for the present and future.

