When to present relationships objects

Hello,

I was looking at the spec but was not able to find answer to the following question, for example I have resource /articles that has relationship to comment.

Consider following request: GET /articles.

a)

{
  // ..
  "type": "articles",
  "id": "19370",
  "attributes": {
    "name": ""
  }
  // ..
}

b)

{
  // ..
  "type": "articles",
  "id": "19370",
  "attributes": {
    "name": ""
  },
  "relationships": {
    "comment": {}
  }
  // ..
}

c)

{
  // ..
  "type": "articles",
  "id": "19370",
  "attributes": {
    "name": ""
  },
  "relationships": {
    "comment": {
      "links": {
        "self": "/articles/19370/relationships/comment"
      }
    }
  }
  // ..
}

Should it return a) or b) or c) acording the specification?

Thank you.

C.

Otherwise you can also provide the data member with the actual relationship data.

https://jsonapi.org/format/#document-resource-object-relationships

Hi,

according to the spec, the type of answer depends on the parameters that you pass in the request.

A simple GET /articles should return the variant a)
While a GET /articles?include=comments could return b) or c) depending on how you decided to implement this. JSONAPI gives the developer the freedom to decide if he/she should include the entire related resource or just a link to it.

Sorry, yes, you are correct. To get the actual comments resources you would need to ?include=comments. The data member I was mentioning are just relationship links to “attached” comments (else [] or null if there are no comments). Either way, I think you have to identify that relationships exist with the response, IMO anyway.

For me it looks quite reasonable too to indentify about possible/existing relationships, but to include actual comments data or not depending on query params. Thanks for suggestions.

@apiator, where does the spec say that GET /articles (without include) should return a)? I’m fairly sure it normally should return c) (as @panman82 originally said), because the client needs the relationship links so it knows where to directly fetch the related resource (or relationship data). (Also, the API is not explorable if relationships require explicit prior knowledge in order to discover and traverse them.)

(If you don’t have relationship links, then c) would include an empty relationship object, and you must exclude it; in that case, a) is correct.)

For clarity: IIRC, according to the spec, the only difference include makes is that the relationship data includes linkage and the related resources are included in the included part of the document. I can’t see it saying that without include, relationship links should not be included.

@cmeeren you are totaly right and thank you for pointing it out. My understanding was somehow biased by my own opinion about how this should be done and I did a superficial lecture of the spec, at least for this aspect of fetching resources, which led me to the wrong conclusions.

That is how I understood it too.
A relationships object would only need "data": { "type":..., "id": ... } if the related object was listed in an includes array?
Otherwise it would just supply the links. Is that correct?

It’s partly correct. All included resources must be linked to from a relationship data property. This is called “full linkage” in the spec. So if you have included resources, they must have a corresponding data in some relationship. (The exception is when the relationships are excluded using sparse fieldsets.)

However, the spec allows providing data for links even when they are not included. Whether that’s useful to you is another matter. I haven’t had use for that yet.

1 Like

I can imagine that is useful for client cache lookup. Say a client has previously cached the result of a related object lookup then it can identify that cache object using the full linkage piece before traversing the related link…

Yes, my thoughts too. However, only the state of the actual relationship is communicated; the object itself might have changed. So you might end up with a correct relationship to incorrect data. But there might of course be cases where that is useful (e.g. relationships changing frequently while the actual entities change infrequently).

Have to think about this. Yes, the client’s cache won’t know about serverside object updates unless it asks for them.