REST:孩子和父母之间的背景

时间:2014-12-02 12:08:25

标签: rest restful-architecture

以下面的URI为例:

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

我对最后一个URI(/ playlists /:id / tracks)有疑问。如何向轨道对象添加与其父播放列表相关的额外信息/上下文?

背景示例:

  1. 将曲目的时间添加到播放列表
  2. 播放列表中的曲目播放次数
  3. 播放列表中每个曲目的喜欢
  4. 所有曲目都有全球范围内创建的时间戳,播放次数和喜欢。所以我的问题是如何将这些信息添加到端点的响应中。

    我现在想出了以下内容:

    {
        "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
        }
    } 
    

    我添加了一个名为relation_to_parent的字段,该字段为孩子与其父母之间的关系添加了一些上下文。我不确定这是否是一个很好的方法。希望听到其他一些解决方案。

3 个答案:

答案 0 :(得分:1)

我不认为有一种真正的方式'去做这个。就个人而言,我不喜欢添加类似的额外信息,因为当您在寻找资源时,您正在提供资源加。在任何情况下,都喜欢'和' created_at'和' play_count'实际上是与父母的关系的一部分,他们不是track本身的一部分吗?

我通常看到的两条路径是:

  1. /playlist/:id/tracks - 返回实际曲目的ID(或网址)列表,然后使用/tracks/:track
  2. 获取
  3. /playlist/:id/tracks - 返回实际曲目,就像您在上面的1中执行了两个步骤一样。
  4. 至于附加信息,如果它不是曲目的一部分,你可以这样做(任何这些都是有效的):

    • 信息作为曲目的一部分,因此/tracks/:track 始终会返回' play_count'和'喜欢'等。
    • 单独的信息,即它自己的资源,如果你想保持轨道清洁。所以你可以在/tracks/:track/social_info/social_info/:track得到它,它与赛道ID 1对1匹配

    如果您有实际的关系信息,那么它取决于它是1:1还是1:N或N:1或N:N。 1:1或1:N或N:1您可能会报告作为资源本身的一部分,而N:N将是资源的一部分(JSON对象可以具有深度)或作为单独的资源。

    就我个人而言,我已经完成了上述所有工作,并且发现更清洁更好,即使它是多次检索。但现在我们正在深入研究意见......

    编辑:

    有很多方法可以做N:N,这里只是一些:

    • /playlist/:id/tracks/:track/social_info - 可以嵌入或链接到另一个对象
    • /social_info/:playlist - 更直接
    • /social_info/playlist/:id如果您可能有不同类型的社交信息

    个人(再次出现这个词;这是个人偏好和观点),每次时间我尝试使用更深层次的路径,认为某些事情在父母背景下才有意义,我有发现自己最终为它创建了自己的资源,然后链接回来,所以第二个或第三个选项最终成为我所做的,第一个链接到它(方便检索它或检索它的列表)。

    大多数情况下,这不是因为服务器端的限制 - 例如当我在nodejs中编写时,我使用http://github.com/deitch/booster来处理到同一资源的多条路径 - 但是因为客户端框架通常在一条真实路径的情况下工作得更好。

答案 1 :(得分:1)

通过1:n关系,您可以定义子资源。通过n:m关系,最好定义一个单独的关系资源。请注意,这些只是最佳做法,而不是标准。

请注意,您可以添加指向其他资源的链接。根据HATEOAS约束,如果要公开操作(例如获取另一个资源),则必须创建超链接。

答案 2 :(得分:0)

如果您想完全接受RESTful服务设计原则,您肯定希望在表示格式中使用超链接。如果您不想提供自己的规范,JSON有一些现有的规范:HALJSON API。天真的超媒体格式可能如下所示:

{
    "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"}}}]
}

HAL和JSON API中包含更复杂的功能,如定义嵌入式资源和链接模板。使用这样的语义,您最终可能会得到以下内容:

{
    "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}
        ]
    }
}

另外,不要忘记使用超链接来表达实体之间的静态关系只是旅程的开始。使用Hypermedia As The Engine Of Application State是真正的涅..但是你可能会瞄准太高。