以下面的URI为例:
/tracks
/tracks/:id
/playlists
/playlists/:id
/playlists/:id/tracks
我对最后一个URI(/ playlists /:id / tracks)有疑问。如何向轨道对象添加与其父播放列表相关的额外信息/上下文?
背景示例:
所有曲目都有全球范围内创建的时间戳,播放次数和喜欢。所以我的问题是如何将这些信息添加到端点的响应中。
我现在想出了以下内容:
{
"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的字段,该字段为孩子与其父母之间的关系添加了一些上下文。我不确定这是否是一个很好的方法。希望听到其他一些解决方案。
答案 0 :(得分:1)
我不认为有一种真正的方式'去做这个。就个人而言,我不喜欢添加类似的额外信息,因为当您在寻找资源时,您正在提供资源加。在任何情况下,都喜欢'和' created_at'和' play_count'实际上是与父母的关系的一部分,他们不是track
本身的一部分吗?
我通常看到的两条路径是:
/playlist/:id/tracks
- 返回实际曲目的ID(或网址)列表,然后使用/tracks/:track
/playlist/:id/tracks
- 返回实际曲目,就像您在上面的1中执行了两个步骤一样。至于附加信息,如果它不是曲目的一部分,你可以这样做(任何这些都是有效的):
/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有一些现有的规范:HAL和JSON 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是真正的涅..但是你可能会瞄准太高。