[英]REST design for API accessing multiple resources
想象一个API,它返回电视列表应用程序(如zap2it TV列表)的 JSON数据。
它基本上是一个电视频道列表,每个频道都有当前及以后的节目。 目前,我有一个返回所有通道GET /channels
的API。 但是,需要为该数据中的每个通道添加当前显示的节目。 我正在考虑添加一个新的API, GET /channels/on_now
,以区别于当前的API。 我想为新API明确这一点,我不想为每个频道单独调用,需要为所有频道返回show-on-now数据。 这是一个很好的REST API设计吗?
当前GET /channels
JSON数据
[
"channel": {
"channelName": "KRON4",
},
"channel": {
"channelName": "KTOV5",
},
...
]
下面的新API GET /channels/on_now
预期JSON数据
[
{
"channel": {
"channelName": "KRON4",
},
"on_now": {
"startTime": "2012-06-04T11:30:00",
"endTime": "2012-06-04T12:00:00",
"shortDescription": "Latest local, statewide & national news events, along with sports & weather.",
"shortTitle": "4:30am Newscast"
}
},
{
"channel": {
"channelName": "KTOV5",
},
"on_now": {
"startTime": "2012-06-04T11:30:00",
"endTime": "2012-06-04T12:30:00",
"shortDescription": "Local morning news and weather report",
"shortTitle": "Morning Newscast"
}
},
...next channel...
]
我建议专注于内容 ,而不是URL。
示例:您有一个入口点'/'。 这是API中唯一的URL。 GET就可以了
{
"channels" : {
"href" : "path.to/channels"
},
"programs" : {
"href" : "path.to/programs"
}
}
要检索通道列表,您需要获取相应的URL(之前您不需要知道),并获取,例如:
[
{
"name" : "BBC",
"id" : 452,
"href" : "path.to/channels/452"
},
{
"name" : "FOO",
"id" : 112,
"href" : "path.to/channels/112"
}
]
有关BBC的详细信息,请在提供的URL上获取:
{
"name" : "BBC",
"id" : 452,
"self" : "path.to/channels/452",
"live_url" : "link.to.bbc.cast",
"whatever" : "bar",
"current" : "path.to/channels/452/current",
"program" : "path.to/channels/452/program"
}
等等。 URL是即时发现的; 你可以随时修改它们。 是什么让你的API成为内容:你必须同意客户关于返回的内容(字段,类型,......)。 您最后调用上面的“当前”URL以获取有关当前程序的信息。
在此阅读更多信息: http : //kellabyte.com/2011/09/04/clarifying-rest/
OP评论后编辑:
您可以引入'embed'参数以限制请求数量:
GET path.to/channels/452?embed=current
会回来:
{
"name" : "BBC",
"id" : 452,
"self" : "path.to/channels/452",
"live_url" : "link.to.bbc.cast",
"whatever" : "bar",
"current" : {
"self" : "path.to/channels/452/current",
"name" : "Morning Show",
"start_time" : "(datetime here)",
"end_time" : "(datetime here)",
"next" : "whatever.comes.ne/xt"
},
"program" : "path.to/channels/452/program"
}
您询问:
这是一个很好的REST API设计吗?
是的 ,是的。
与已经回答的其他人相反,您可以自由定义您想要的任何资源,只要它代表名词。 这包括与时间相关的服务,例如“现在在电视上播放什么”或者是“<city>中的当前天气”。 这些服务资源与表示节目或频道的更多静态资源一样有效。
但是我会更改URI。 /channels
看起来像集合资源URI。 我希望它的子/channels/kron4
是通道,例如/channels/kron4
(你可以使用任何唯一的字符串,而不是jsut ID,来识别实例资源)。
因此, /channels/on_now
看起来很奇怪。 它看起来像一个名为“on_now”的频道。 虽然没有什么阻止您使用的是,它可以后用信道冲突被称为“现在开”! 我只想使用/on_now
作为你的URI。 /channels/kron4/on_now
显然也适用于单个频道的响应。
/Channels -----------------------> Get All Channels
/Channels/bbc ------------------> Get BBC Channel
/Channels/bbc/Shows -------------> Get All shows in BBC
/Channels/bbc/Shows/Baseball ----> Get the show called "Baseball", in bbc channel
/Channels/bbc/Shows/current -----> Get the Current show running, in bbc channel
假设您没有(并且不会)为您的任何频道播放名为Current
的节目! :)。
只是附上上面的答案:
/Channels/bbc/Shows/time/now -----> Get all the show played on BBC now
/Channels/bbc/Shows/time/2011-03-27T03:00:00.000+02:00 -----> Get all the show played on BBC on 2011-03-27T03:00:00.000+02:00 .
这是更具可扩展性的,您不必担心任何名为current的节目。
编辑:如果你可以通过这里获得api-doc访问权限,你可以做一个很好的事情开始这样做https://developer.sdp.nds.com/page/about
按照我的说法,需要更多数据,api就像:// epg?time =&start = 0&limit = 1&duration =
这将定义通用api以基于时间和持续时间获得基于位置的tv_listing信息。 结果将在给定时间跨度内出现的频道列表之间的所有节目中分页。
我不是API专家,但我认为你应该考虑你要回来的东西而不是放置资源的“看起来有意义”。
一种解决方案是将on_now视为资源。
所以你的api将是:
/channels (all channels)
/channels/{channel-id} (the {channel-id} channel - could be bbc and can have a collection of shows)
/channels/{channel-id}/shows (shows of channel-id)
/channels/{channel-id}/shows?filter=on_now (you are filtering a result, so i guess it's better to use query string, as if you were doing a query)
然后你想要返回现在的内容,这不是频道的属性,而是自身的资源。 那怎么实现呢?
/on_now/ (return a collection of on_now objects, which may be anything, channels, shows, whatever)
/on_now/?channel={channel-id} (this is a filter of the list by channel-id, you are just narrowing the list)
所以不是/channels/{channel-id}/shows?filter=on_now
与/on_now/?channel={channel-id}
?
实际上, 不 。
在第一个uri中,您将获得由on_now过滤的节目。 在第二个中,您将获得按频道过滤的on_nows(可以是任何表示,而不仅仅是显示)。
为什么我认为on_now
应该被视为一种资源,为什么它很重要?
当您将此资源分开时,您现在可以对资源进行不同的表示。 您还具有更大的灵活性和无碰撞。 让我们说明天你想要在on_now中显示另一个不在任何频道上的'节目',这很容易就可以完成,而其他方法只需要在频道上。 您也可以稍后按不同的标准过滤on_now,因为它们是独立的对象。
你也可以这样做:
/on_now/{on_now_id}
这将提供当前节目的详细信息,例如它何时开始,什么时候结束,还有一个位置到/shows/{show-id}
以便您可以在它现在不再使用之后到达它。
然而,我认为最好的解决方案是将节目作为一种无关的资源来进行宣传。 但最重要的是, 我认为你还应该问问自己,你是否希望节目成为频道的基础......还有什么提示可以想到这就是
I don't want to make individual call for each channel, the show-on-now data needs to be returned for all channels
部分。
这让我觉得节目不应该在/channels/
path里面。
那是因为如果你只返回节目,另一种方法是/shows/?filter=on_now
。
你可以有:
/shows/?filters=on_now&channel=bbc
我喜欢将资源视为我回归的“事物”,而不仅仅是关系的标准思维。 图中的底层对于属性来说是很好的,对于“其他东西”的收集并不那么确定。
按照相同的例子,我宁愿使用/channels/{channel-id}/program
而不是/channels/{channel-id}/shows
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.