I've been wondering about how far to go with links in REST. Consider books which have authors, but there is obviously a many-to-many relationship between books an authors (a book can be written by multiple authors, and authors can write multiple books).
So let's say we have a rest call http://server/book/21
, which will return a book XML, containing information about an author. Now since the book is a resource, and the author is a resource, the XML should not straight up include all the author information. It should contain a link to the author information. But which of the below two examples is more widely accepted?
(Excuse my crappy formatted XML, I am not that experienced with hand writing XML)
<book>
<title>Some Book</title>
<authors>
<author link="http://server/author/82">Some Guy</author>
<author link="http://server/author/51">Some Other Guy</author>
</authors>
</book>
Then, an author link would return more information:
<author>
<name>Some Guy</name>
<dateOfBirth>some time</dateOfBirth>
</author>
Or:
<book>
<title>Some Book</title>
<authors>http://server/book/21/authors</authors>
</book>
Where http://server/book/21/authors
returns:
<authors>
<author link="http://server/author/82">Some Guy</author>
<author link="http://server/author/51">Some Other Guy</author>
</authors>
And then each of those returns the former <author>
example again.
The reason I'm asking is basically because at my job they went with the second approach, and it seems to me that clients have to take many more steps to reach where they want to go. Also, for basic information which "you're always going to need" (author's name), you do have to take one additional step.
On the other hand, that way the book
resource only returns information about the book (nothing else), and to get anything else, you have to access other resources.
This question sounds more like a "what is your preference" type of question. So here is my 2 cents:
It seems to me like including the author names in the original xml will be the best idea. This will allow the client application to display a list of hot-linkable author names, without requiring a second rest request. Author names are most likely always displayed when the book resource is. If I were you I would focus more on the practicality, than worrying about the "theoretical" correctness of the rest resource. If that makes any sense.
You don't have to include all of the author's information in the original xml resource. Rather what is practical for displaying the book resource, and finding more information about the author when/if needed.
As long as it's done consistently....
Either may seem fine, but I actually put my money on the second approach is more flexible to allow for future API growth in a consistent manner. This is because you may have more than an handful of relations of different objects to the main object. To get a single object back with a ton of links to different objects might be a pain to deal with. Also, it limits the size of the object being return to just the core 'book' information, not the other various objects it's related to, even if they seem inserperable. Go for the the minimal useful component for each resource, at the very least reduces unneeded load on your backend as well for relations not really being used.
Sure, in this example it's hard to see the importance of limiting the relationship info in an object, since most books only have a few authors at most, but is that the case for all objects you expose via REST? Imagine if this was a 'bookstore' and the relationship was 'customer'. If you just wanted the store address and phone number, would it be not be very wasteful for all parties you also need to pull back a full list of customers and make it part of the object? An so you make an exception for this new case and not return customers as links, but for another thing like store department you decide to include them as links? Now you've got an inconsistent and your customers need to learn which way each objects get returned as they all don't fit the same pattern.
The second also keeps the relational model clean if this same approach is done universally throughout your API. Any object's relations are accessed through:
http://server/object/<object_id>/<relationshipName>