Related resource of other independent resource type


#1

According to JSONAPI example, articles is related to author resource. This author resource is of type people.

To my understanding, there will be independent resource /people and /articles is related to /people using author. If so, then the author is a subresource of /articles ? - the author cannot exist without an article and this subresource is maintained as relationship and can be called via relationships related link - /articles/1/author which returns people resource primary object [who belongs to article 1]

Kindly state if my understanding is correct or if I misunderstood something with JSONAPI spec?


#2

The relationships are not resources, they are names for the links between two resources.

The author is a people resource. The relationship of the article and the people is author, this people resource wrote this article. The people resource exists independent of the article and vice versa. The relationship of the two resources is what is called ‘author’.


#3

hi @michaelhibay, thanks for the reply and apologize for the delayed reply from my side.

These relationship names need not be a standalone resources. If i query /articles/1/author It will fetch me with people resource object who wrote article 1. In a one-to-many relationship, is there any way to apply filtering on these relationship related link which involves relationship name and not the independent resource itself.


#4

The relationship itself is already a subtle form of filtering. I see no reason in the spec or implementation details you can not filter on the /articles/1/relationships/tags?filter …

Let’s be clear, the example in the spec, is poor because it isn’t unique enough to really explain the difference between self and related.

"author": {
  "links": {
    "self": "/articles/1/relationships/author",
    "related": "/articles/1/author"
  },

The Author resource in this example is a sub resource of articles, which is a poor design but also confusing as an example. The following would be better.

"author": {
  "links": {
    "self": "/articles/1/relationships/author",
    "related": "/people/1"
  },

The relationship is author, it is how they are related, but the related resource object would be found at /people/1 not as a sub resource of the article itself. This isn’t bike shedding over the design, but a fundamental principle of API design. This more clearly demonstrates the difference between the relationship and the target resource of the relationship.

With these examples you can clearly see the ruby roots of the specification by its adherence to ruby-rest design which is entirely functional, but does not scale or evolve well.


GET /articles/1/relationships/comments and a GET /articles/1/comments
#5

If the related link should point to the related resource with its independent resource link. What will be the link for a one-to-many relationship? article and comments in the spec example.

/articles/1/comments will be the related link for comment relationship with article.

Referring many discussion I found that this link would fetch collection of comment resource objects belonging to article 1. This will be similar to /comments?filter[article]=1


#6

The data format for a to many relationship would be this, from the spec.

"links": {
  "self": "/articles/1/relationships/tags",
  "related": "/tags?filter[articles]=1"
},
"data": [
  { "type": "tags", "id": "2" },
  { "type": "tags", "id": "3" }
]

Based on your inclusion of the comments example, it seems you are on the right track.


#7

Slightly extending on this scenario. I am all in favour of this approach, but would you also include the absolute/foreign resource links for each element in the data section? This is where the spec is not very helpful.
E.g. would it be allowed to include a hypermedia reference (eg. href) for each type/tag entry in the data section? /tags/2 and /tags/3 in your example? I would expect the absolute hypermedia reference to be constructed by the provider and not make assumptions on the consumer side?
Thanks


#8

The relationship “tags” is the hypermedia. There is nothing to suggest the resource on the other side needs to be called a “tags”, but as the “resource identifier object” has the type “tags” you know the type of that resource is that type. Those two items do not need to match. You could have a “tags” relationship pointing to a “postitems” resource with a URL of “/9818jfadl?filter[article]=1,[type]=tags”

This will map to the resource name the client has discovered, cached, or will discover from the root URL. This last part is why people say the URL is opaque, when properly hypermedia driven it doesn’t need to make sense to a human.

I’m not suggesting this design, but using it to illustrate the point. Your client already has the information it needs to link the resource definitions it already has to the response data it receives. If you want any more explicit information use JSON-LD as the standard way to do this, but know you are severely bloating your response with redundant data if you choose that route. I wouldn’t’ suggest doing so, until you have a very good understanding of how exactly it would help you, and the negatives which come along with it.