Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST: Context between child and parent

Take the following URI's as an example:

/tracks
/tracks/:id
/playlists
/playlists/:id
/playlists/:id/tracks

I have a question about the last URI (/playlists/:id/tracks). How do I add extra information/context to the track objects in relation to it's parent playlist?

Examples of context:

  1. Added time of the track to the playlist
  2. Play count of the track within the playlist
  3. Likes per track within the playlist

All tracks have a created timestamp, play count and likes on a global scale. So my question is how would this information be added to the response of the endpoint.

I've come up with following for now:

{
    "title" : "harder better faster stronger",
    "artist" : "daft punk",
    "likes" : 234252,
    "created_at" : "2012-10-03 09:57:04"
    "play_count" : 1203200035,
    "relation_to_parent": {
        "likes" : 5,
        "created_at" : "2014-11-07 19:21:64",
        "play_count" : 20
    }
} 

I've added a field called relation_to_parent which adds some context to the relation between the child and it's parent. I'm not sure though if this is a good way to do it. Hope to hear some other solutions.

like image 696
Boedy Avatar asked Dec 07 '25 22:12

Boedy


2 Answers

By 1:n relations you can define a subresource. By n:m relations it is better to define a separate relationship resource. Note that these are just best practices, not standards.

Be aware that you can add links pointing to a different resource. According to the HATEOAS constraint you have to create hyperlinks if you want to expose an operation (for example getting another resource).

like image 62
inf3rno Avatar answered Dec 09 '25 15:12

inf3rno


I don't think there is a 'one true way' to do this. Personally, I dislike adding the extra information like that, since you are giving a resource-plus, when you are looking for a resource. In any case, are 'likes' and 'created_at' and 'play_count' actually part of the relation to the parent, aren't they part of the track itself?

The two paths I usually see for this are:

  1. /playlist/:id/tracks - returns a list of IDs (or URLs) for actual tracks, which you then fetch with /tracks/:track
  2. /playlist/:id/tracks - returns the actual tracks, as if you did both steps in 1 above.

As for additional information, if it is not part of the tracks, you might do it as (any of these is valid):

  • info as part of the track, so /tracks/:track always returns the 'play_count' and 'likes', etc.
  • separate information, i.e. its own resource, if you want to keep the track clean. So you might get it at /tracks/:track/social_info or maybe /social_info/:track where it matches the track ID 1-to-1

If you have actual relation information, then it depends if it is 1:1 or 1:N or N:1 or N:N. 1:1 or 1:N or N:1 you would probably reports as part of the resource itself, while N:N would either be part of the resource (JSON objects can have depth) or as a separate resource.

Personally, I have done all of the above, and find cleaner is better, even if it is multiple retrievals. But now we are delving into opinion....

EDITED:

There are lots of ways to do N:N, here are just some:

  • /playlist/:id/tracks/:track/social_info - which could be embedded or a link to another object
  • /social_info/:playlist - more direct
  • /social_info/playlist/:id if you might have different kinds of social info

Personally (there is that word again; so much of this is personal preference and opinion), every time I have tried using deeper paths, thinking something only makes sense in a parent context, I have found myself ending up making its own resource for it, and linking back, so the 2nd or 3rd option ends up being what I do, with the first linking to it (either convenience to retrieve it or retrieve a list of it).

Mostly, that has not been because of constraints on the server side - e.g. when I write in nodejs, I use http://github.com/deitch/booster which handles multiple paths to the same resource really easily - but because client side frameworks often work better with a one true path.

like image 44
deitch Avatar answered Dec 09 '25 15:12

deitch