Should relationship paths be supported outside of inclusions?

Assume a resource user. This resource defines a relation named parent, which points to another user.

Inclusion of related resources mentions relationship paths to refer to deeply “nested” relatives.

I am wondering if these kinds of paths should be supported when, for example, simply fetching a related resource. For example, /user/123/parent.parent to fetch the grandparent.

I didn’t see this being mentioned in the spec, but I felt like it should be. If this path mechanism exists in another area, I feel like consumers of the API would expect this to work in other areas.

Am I mistaken? Is this sort of query already covered by another approach I’m currently not seeing?

You aren’t mistaken, I don’t think this type of behavior is included in the spec directly. I think this type of behavior would fall under the filtering section, which would require a filtering strategy definition. There are various strategies for obtaining this kind of functionality technically, however I would advise you to reconsider the urge to add complex querying capabilities before you have explored some semantic solutions.

While I often advocate designers to keep the resource hierarchy as flat as is reasonably possible, in this case you could introduce a family tree sub resource which could semantically define N level of relationships from a particular user, and could even be queried to a particular depth from the user via filtering on a depth constraint.

In this way you could return /user/123/familytree?filter[depth]=2 and return relationships of parent, grandparent, great-grandparent with resource ‘objects’ or ‘resource identifier objects’ as desired.

If you are reaching in the bag for a way to carefully sculpt data for a particular concept, there is very likely to be value in creating reusable semantic driven resources to better explain in human terms the relationship between two or more resources.

Thanks again for this great feedback.

I don’t want the discussion to be held back by the specific example. I’m currently implementing the API layer very generically for our existing resource definitions which exist in our application stack. Our system for modeling those definitions allows relationships to be modeled. I’m only trying to see all ways in which I have to expose our data so that it is JSON:API compliant and intuitive.

When I read about inclusion of related resources, I assumed that this pattern of specifying deeper relationships as targets would repeat throughout the entire JSON:API spec. This is not the case, as I understand now.

Where I am currently at in regards to the implementation, allowing deeper relationships to be queried like I was suggesting would actually negatively impact performance in a way that I would rather omit it.

When we later see an actual demand for querying data like this, we will probably go with a filtering-based approach like you were suggesting.

Json API for better or worse is not ‘fully’ opinionated on hypermedia use, which it should be in my opinion. I suggest the filter approach as the specifications ‘crud’ API style solution for the problem, however as I think you have seen, the hypermedia solution is not only more intuitive but far more flexible long term with regards to upgrading your resource models in the future without breaking clients or compatibility.

The filter strategy is explicit which requires you to understand the resource relationship models before you are able to retrieve the information you seek. Utilizing a hypermedia vocabulary which is universally understood, as in my example, is a much better solution for integrators and API designer alike.

A quote I read recently but can’t remember the source “when you change your API version, its a new API”. Consider this when thinking about the weight of legacy code if you do not control the consumer clients, as hypermedia will provide a flexible platform which can be maintained overtime as opposed to a crud API which is extremely inflexible and brittle. People like to put off large bites until there is a ‘need’, however you only get one shot to design the interaction model of your API.

2 Likes