REST: context between child and parent

Take the following URI as an example:

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

      

I have a question about the last URI (/ playlists /: id / tracks). How can I add additional information / context to track objects relative to the parent playlist?

Examples of context:

  • Added track playback time to playlist
  • Number of tracks played in the playlist
  • Likes by track in playlist

All tracks have a generated timestamp, play amount and like globally. So my question is how to add this information to the endpoint's answer.

At this point I have come up with the following:

{
    "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 added a field called relation_to_parent which adds some context to the relationship between the child and parent. I'm not sure though if this is a good way to do it. Hope to hear other solutions.

+3


source to share


3 answers


I don't think there is "one true way" for this. Personally, I don't like to add additional information, for example, since you give resource-plus when looking for a resource. Anyway, "like" and "created_at" and "play_count" are actually part of the relationship to the parent, aren't they part of it track

?

The two paths I usually see for doing this are as follows:

  • /playlist/:id/tracks

    - returns a list of ids (or urls) for real tracks, which are then fetched with /tracks/:track

  • /playlist/:id/tracks

    - returns the actual tracks as if you did both in 1 above.

As for additional information, if it is not part of the tracks, you can do it like (any of them are valid):

  • as part of a track, so it /tracks/:track

    always returns "play_count" and "like", etc.
  • separate information, i.e. own resource if you want to keep the track clean. So you can get it at, /tracks/:track/social_info

    or possibly /social_info/:track

    where it matches the 1-to-1 track id

If you have actual information about the ratio, then it depends on whether it is 1: 1 or 1: N or N: 1 or N: N. 1: 1 or 1: N or N: 1, you are probably reporting as part of the resource itself, whereas N: N will either be part of the resource (JSON objects can have depth) or as a separate resource.



Personally, I've followed all of the above and it's best to find a cleaner, even if it's multiple searches. But now we delve into the opinion ...

Editorial staff:

There are many ways to do N: N, here are just a few:

  • /playlist/:id/tracks/:track/social_info

    - which can be inline or reference to another object
  • /social_info/:playlist

    - more direct
  • /social_info/playlist/:id

    If you can have different types of social information

Personally (this word again, so much of it is personal preference and opinion), every time I tried using deeper ways, thinking that something only makes sense in a parental context, I have found myself in I end up creating my own resource for it and linking to it, so the second or third option ends up with what I do, with the first binding to it (either convenience to get it, or get a list of it).

Basically, this is not due to server side constraints - for example when I write in nodejs I use http://github.com/deitch/booster which handles multiple paths to the same resource very easily, but since the framework the client side often works better with one true path.

+1


source


In a 1: n relationship, you can define a subresource. It is better to define a separate resource of relations by n: m relations. Please note that these are simply best practices, not standards.



Remember that you can add links that point to another resource. Due to the HATEOAS constraint, you must create hyperlinks if you want to open an operation (for example, get another resource).

+1


source


If you want to make full use of the design principles of RESTful services, you definitely want to use hyperlinks in your presentation format. JSON has some existing specifications if you prefer not to come up with your own: HAL and JSON API . A naive hypermedia format might look like this:

{
    "playlist_id" : "666",
    "created_at" : "2014-11-07 19:21:64",
    "likes" : 5,
    "tracks" : [
        {"index" : 1,
         "begin_at" : "00:02:00",
         "end_at"   : "00:05:23",
         "_links" : {"track" : {
             "href" : "/tracks/123",
             "type" : "track"}}},
        {"index" : 2,
         "_links" : {"track" : {
             "href" : "/tracks/432",
             "type" : "track"}}},
        {"index" : 3,
         "_links" : {"track" : {
             "href" : "/tracks/324",
             "type" : "track"}}},
        {"index" : 4,
         "_links" : {"track" : {
             "href" : "/tracks/567",
             "type" : "track"}}}]
}

      

More complex functionality is included in both the HAL API and JSON, such as defining inline resources and link templates. Using semantics like this, you can end up with something like the following:

{
    "id" : "666",
    "created_at" : "2014-11-07 19:21:64",
    "likes" : 5,
    "tracks" : [
        {"id" : "123",
         "index" : 1,
         "begin_at" : "00:02:00",
         "end_at"   : "00:05:23"},
        {"id" : "432",
         "index" : 2},
        {"id" : "324",
         "index" : 3},
        {"id" : "567",
         "index" : 4}
    ],
    "_links" : {
        "_self" : {
            "href" : "/playlists/666",
            "type" : "playlist"},
        "tracks" : {
            "href" : "/tracks/{id}",
            "type" : "track"}
    },
    "_embedded" : {
        "track" : [
            {"id" : "123",
             "title" : "harder better faster stronger",
             "artist" : "daft punk",
             "created_at" : "2012-10-03 09:57:04",
             "likes" : 234252,
             "play_count" : 1203200035},
            {"id" : "432",
             "title" : "aerodynamic",
             "artist" : "daft punk",
             "created_at" : "2009-03-07 11:11:11",
             "likes" : 33056,
             "play_count" : 8796539}
        ]
    }
}

      

Also, keep in mind that using hyperlinks to express static relationships between objects is just the beginning of the journey. Using Hypermedia as an application state mechanism is real nirvana ... but then you can get too dependent.

0


source







All Articles