I've been trying to build a hypermedia based API. Things seem working well. Say when I fetch /books/isbn/12313441213
I get something like this:
<book>
<id>123</id>
<name>Hypermedia APIs</name>
<description>Basic api design techniques</description>
<tags>
<tag>rest</tag>
<tag>api</tag>
<tag>service</tag>
</tags>
<authors>
<link rel="author" uri="/authors/id/22" />
<link rel="author" uri="/authors/id/18" />
</authors>
</book>
Now I can traverse the authors from this resource. When I fetch /books/by/author/id/18
I get something like this:
<books>
<book id="123">
<name>Hypermedia APIs</name>
<link rel="self" uri="/books/id/123" />
</book>
<book id="191">
<name>Chef Recipes for Rails Developers</name>
<link rel="self" uri="/books/id/191" />
</book>
<book id="220">
<name>Rails 4 Cookbook</name>
<link rel="self" uri="/books/id/220" />
</book>
<book id="292">
<name>Ruby 102</name>
<link rel="self" uri="/books/id/292" />
</book>
<book id="432">
<name>Semantic Architecture</name>
<link rel="self" uri="/books/id/432" />
</book>
<book id="501">
<name>Service Oriented Design</name>
<link rel="self" uri="/books/id/501" />
</book>
</books>
Which also seems to be working fine for me. Whether or not this way of uri templating is good, my question is around how practical to traverse links like this?
Considering you want the resource in full-depth (including author details), you have to make at least 3 calls to the server. Again for the collection, you have to make tons of calls to the server. Yes maybe I could utilize resource expansion here, but then why would I use hypermedia links at all since all of my clients will be using expanded resources in time.
I understand we are gaining lots by letting clients to traverse links (ie. if clients build relation based resource discovery, they will be impacted minimum when we change the api, or they are forced to get the most recent schema from the resource endpoint itself, etc). Then again, practicality of this approach, or the performance of this approach would kill the system.
Either I'm not getting something in hypermedia api design, or hypermedia api sounds great but it seems it's just a theoretical idea, not a practical one.
Any thoughts on this?
It would be more traditional to use parameters:
GET /books?author=18
I would expect that the response would look more like:
Hypermedia APIs
You can also use a parameter to indicate what fields on sub-resources you want visible. Something like
GET /books/18?expand=author(name, birthday)
which would return the author's name and birthday as part of the author tag in the response. Then you can provide a reasonable default for how much author information users get when they ask for a book (maybe just the author's self and name), but they can get more details if they want by altering the parameter.
Those kinds of customization can help cut down on the number of calls that need to be made.
Another observation is that a lot of this data can be cached, either on the client or on intermediate proxies. It's not likely that much will change about a book or an author, so those resources can let the client cache them for a long period of time. Then there's no round trip at all - the client hits their own local cache for the data.