Relationship with itself

Hey,

I am wondering if there is a best practise for resources that have a relationship with themselves. For example if I have an images resource and an image can have different images related to them, like a mobile version of the image.

My main question is how I would name the relationship.

I can not use image for both the relationship and the inverse relationship, obviously.

So would the image have a relationship images which would give me all related “child” images and a relationship parentimages that would give me the parent `images? “Parent” by itself does not work, because a back and forth relationship might also exists for more tables.

e.g. a comment could be related to an image as in “comment in the image” but an image could also be related to a comment as in “an image inside a comment”.

I hope you understand my naming problem. I need some kind of rule, so that an api user knows how to retrieve those kinds of relationships.

Does it really make sense to model “image” as a primary resource? Or are there rather a collection of images that relate to some other resource (e.g. the thing depicted in the image)?

I am not sure how you mean this? Can you explain it in a little more detail? Maybe you can give me an example of how you would model it?

However I also have other things, like a collection, which could hold images, but it could also hold some collections.

I’d need a bit more information about your domain to do that.

Another point that might be relevant is that a JSON API link must always return a JSON API response, it cannot return another media type (such as an image), so at some point you may well have to put image URLs in attributes rather than in a relationship.

Hey, sorry, that was probably badly put.

An Image means a json response for an image, e.g. a link or file location, name, etc. So images is a resource itself.

I’d need a bit more information about your domain to do that.

What do you mean by this?

I’m still a bit confused about what these images are of. Are they all of the same kind of thing, or lots of different kinds of thing?

I’m also not sure how the different images vary from each other. Is it just resolution? Or encoding type? Or dynamic range?

Are you build an image manipulation API, or are images just one aspect of something else you’re primarily concerned with?

Hey, I am building a content API, images are just one part.

There are different images, and those can have different resolutions.

Another example of this kind of relationship is a collection. A collection can have different types of content, e.g. images or pages. But it might also be a collection of collections (think category that is related to image galleries).

I am trying to keep the data as flexible as possible, because I can not plan for every possibility.

Currently I just have relationships like this:

Collections
collections = the Collections that are in the collection
ownedByCollections = inversere; the Collections that own this collection

So you’re building something like a CMS?

Are the potential content types predetermined, or can users upload arbitrary content and create their own classifications & linkages? If so, then something like GraphQL might be a more appropriate technology…

I’m a bit surprised by this. Do you really mean “owned by” or would this be better expressed as “containedIn”?

I’m a bit wary about this. It’s not necessarily wrong, but aren’t there more specific relationships you can use? (I suppose this might depend on your answer to the earlier question about user-created content.)

Hey, sorry for the late reply, I was on vacation.

  1. Yes, a CMS with an api which can be access from outside of the cms.

  2. No the content types are predetermined. However I will start with a fairly simple system and want to extend it over time. For this reason I need to be able to make changes without touching the database as much as possible, since I do not want to update a database with client data in it, if I can avoid it.

  3. I chose “ownedBy” because I can more universally use it. I do not want to have different naming for every endpoint, as this will make it a lot harder to learn. While a page can be “containedIn” a collection, it feels weird, to say a page is “containedIn” a page, but this is possible (creating subpages), which are not contained in the main page, but children of those.

  4. I do not really get it, sorry, can you explain this a bit more? :sweat_smile:

PS: Thanks for taking the time to help me, I really appreciate it.

I can understand a desire to avoid breaking changes, but there should be no problem adding new columns or tables to your schema.

If your content types are predetermined (even though not all will be present in your first release) then I would prefer to use more specific relationships between the different data types, rather than generic parent + child or container + contents or collection + members. It might make sense to generalise like that in the API implementation, but isn’t that just a way to reduce the amount of code / effort required? Don’t the API clients / CMS users have different expectations / mental models of how things relate? The API should be easy to consume and matching the consumer’s view of the world is a good way to achieve this (though the implementation behind the API doesn’t have to use the same structure).

I might be able to explain better with examples if I knew more about who you think your users are, and why they want a CMS.

So you are saying you think for an api user (read developer using the api) it would be easier to have containedInCollection, but ownedByPage because it makes more sense in english? I understand your argument, but feel it would actually make it more complicated than having a solution that is the same for every resource.

Okay, but apart from the naming, would you say the approach I described is sensible?

I’d be trying to make it even more specific.
I’m not really sure what you’re suggesting the relationship between image galleries and categories is; but assuming each gallery has a primary category, and that multiple galleries can be assigned to the same category, I’d be thinking about using category rather than containedInCollection to link back from the gallery to the category.
For child pages I’d be thinking of using parentPage rather than ownedByPage to link back from the child page to the parent page.

But I’d also want to consult with the users of the CMS to understand what they call these various relationships. i.e. I’d want to explore the DDD idea of a “ubiquitous language”

Hey, okay, now I get it. :smile:

Yes, I totally see your point. I did not due it, because the other way made it easier to automate some parts (although I have an idea on how to automate it with a more DDD approach as well).

Not everything is so easy to pin down to one specific thing, like category, but most are. I will try to implement something like this. Thank you very much. :+1:

Hi.
Sorry for “stealing” the thread, but the title fits perfectly for me as well.
What if you have a users resource that can have a to-many relationship with other users resource (like a FB connection).
Should the related link be something like /users/<user_id>/users ?
This sound a bind odd, I would prefer something like /users/<user_id>/friends, but then I think the returned resources should be of friends type and not users type correct?

Cheers

The content of the URL is much less important than the name of the relationship, but it will make for easier debugging / analysis if there is a good correlation between the name and the URL.

It is recommended that the returned resource would be a friend rather than a user (see here), but this is not required.
It depends on your domain, but I would expect there to be some difference between the data exposed by a friend and by a user. For example, a friend might have a related resource of mutual friends (whereas a user couldn’t because this depends on the context).

Understood.
Thanks @jlangley