Do I need to include explicit links in my relationships.data elements?


#1

Hi!

Let’s say I want to build an API that will allow a musician to retrieve a list of the bands they’re currently playing in, and then a list of forthcoming shows for each of those bands.

So, I do an HTTP GET /musicians/1234, which returns something akin to…

{
  "data": {
    "type": "musician",
    "id": "1234",
    "attributes": { /* stuff here */ },
    "relationships": {
      "bands": {
        "links": {
          "self": "/musicians/1234/relationships/bands",
           "related": "/musicians/1234/bands"
        },
        "data": [
          { "type": "band", "id": "56" }, 
          { "type": "band", "id": "78" }
        ]
      }
    }
  }
}

So - I know this musician is in two bands, and I know those bands IDs - but how do I use this information? Do I need to explicitly include a links collection in each element of the relationships.bands.data array? Do I need to make sure my API supports GET /band/56 so my client can create URLs from the resource identifier objects?

It looks to me like all I can do with the above representation is to do another GET to /musicians/1234/bands - in which case there’s very little value in including the data { } element in the relationships.bands element. I suspect I’ve misunderstood the purpose of the relationships/bands/data element, but I can’t see what the correct solution should be.

Thanks!

Dylan


#2

Hi Dylan! The primary purpose of the data element in a relationship is to provide linkage information in a compound document. You can include related resources by default or by request (via an include param). See the Inclusion of Related Resources section for details.


#3

Right, as @dgeb mentioned, the purpose of "data" is primarily for compound documents and, right now, all you can do is request the whole collection /musicians/1234/bands, rather than each individual band (though you can paginate that collection, if needed).

There’s also a proposal, which I’m about to take up again in a new issue, to add an "href" member or similar to each item in "data" so it can be be requested individually. So far, though, this hasn’t been a huge priority, as the "related" link generally suffices.


#4

OK, so in this situation (assuming no use of resource includes), I would be…

  1. GET /musicians/1234
  2. Find the links.related element (/musicians/1234/bands/)
  3. GET /musicians/1234/bands

which will return something akin to

and finally, do a GET to each of the item.shows.related URLs to get an array of forthcoming shows for that band?

It then follows that to reduce the number of requests, I could specify

GET /musicians/1234?include=bands.shows

which would cause my server to return a response like

The only thing that still isn’t clear is that in this example, I’ve omitted the links and relationships elements from the show resources in the included element of the response. In real life, should these elements be included, excluded, or is that at the implementer’s discretion?

Thanks so much for your help - much appreciated.


#5

Including "links" in the related shows or not is at the implementor’s discretion, since "links" is always optional. Still, I’d suggest including it (for consistency and since it can be useful). The "relationships" bag on the "included" shows should definitely be included, since omitting it would signal to clients that each show has no relationships. However, if a client doesn’t care about the shows’ relationships, it can explicitly request to just get the date and venue like so:

GET /musicians/1234?include=bands.shows?fields[shows]=date,venue

And, in that case, the "relationships" key could on the shows could be omitted entirely.

Thanks so much for your help - much appreciated.

Absolutely :smile: