Skip to content

Instantly share code, notes, and snippets.

@odrotbohm
Created April 26, 2012 07:21
Show Gist options
  • Save odrotbohm/2497116 to your computer and use it in GitHub Desktop.
Save odrotbohm/2497116 to your computer and use it in GitHub Desktop.
Spring Data REST - Link representation options
1. Current state (1.0.0.M1)
---------------------------
+ Aligned with the XML definition of atom:link.
- Harder to work with for JavaScript clients
GET /root
200 OK
{ _links : [ { rel : "persons", href : "/root/persons" },
{ rel : "accounts", href : "/root/accounts" }]}
2. Alternative
--------------
+ Easier to work for JavaScript clients.
- Custom link scheme introduced
- Multiple links with same rel impossible (see below)
GET /root
200 OK
{ _links : { persons : "/root/persons",
accounts : "/root/accounts" }}
3. Problematic scenario with 2.
-------------------------------
A GET to a collection resource currently returns a list of links, not representations, which would create duplicated keys for the fields.
GET /root/persons
200 OK
{ _links : { person : "/root/person/1",
person : "/root/person/2" }}
This is of course invalid but we could tackle this problem in two ways:
3.1. Plain link lists without rels
----------------------------------
As the rel for the returned links is implicitly known by the collection resource (a GET to a persons resource, returns links pointing to person resources). We could simply return a list of links then:
GET /root/persons
Accept: application/json
200 OK
[ "/root/person/1", "/root/person/2" ]
or
200 OK
{ _links : [ "/root/person/1", "/root/person/2" ] }
GET /root/persons
Accept: text/uri-list
200 OK
/root/persons/1
/root/persons/2
3.2. Return representations instead of links
--------------------------------------------
Alternatively we could return a more verbose representation of the persons already:
GET /root/persons
200 OK
{ persons : [ { firstname : "Dave",
lastname : "Matthews"
_links : { self : "/root/persons/1" }},
{ firstname : "Carter",
lastname : "Beauford",
_links : { self : "/root/persons/2" }
],
_links : { _next : "/root/persons?page=1&size20" } }
We did not decide for that approach in the first place as if done naively we might return all the resources which results in an unbearable payload and unnecessary network traffic. An approach to work around this is paging by default, which means we will return only a subset of the resources by default and provide links to navigate the collection.
@kdonald
Copy link

kdonald commented Apr 26, 2012

It may feel weird but this is a very common case and question you will need to answer. I tend to agree treating them as separate resources is the right way to go. Nearly all the major APIs on the web separate out their API from their web site. Facebook, Twitter, Github, etc. So in those cases they're separate resources. Having complexity introduced at the HTTP routing layer in the name of REST "purity" smells of overengineering and unnecessary complexity to me. Browser Accept Headers also can't generally be relied upon, and a dedicated API subdomain separate from www is often desired.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment