想象一个API,它会为zap2it TV listings.
等电视广告资源应用返回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...
]
答案 0 :(得分:3)
我建议专注于内容,而不是网址。
示例:您有一个入口点'/'。这是API中唯一的URL。得到它就像
一样{
"channels" : {
"href" : "path.to/channels"
},
"programs" : {
"href" : "path.to/programs"
}
}
要检索频道列表,您需要获取相应的网址 - 之前您不需要知道 - 并获取,例如:
[
{
"name" : "BBC",
"id" : 452,
"href" : "path.to/channels/452"
},
{
"name" : "FOO",
"id" : 112,
"href" : "path.to/channels/112"
}
]
有关BBC的详细信息,请在提供的网址上获取:
{
"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"
}
答案 1 :(得分:2)
你问:
这是一个很好的REST API设计吗?
是,是。
与已回答的其他人相反,您可以自由定义任何您想要的资源,只要它代表名词。这包括与时间相关的服务,例如“现在在电视上播放什么”或者在例如“< city>”中的当前天气。这些服务资源与表示节目或频道的更多静态资源一样有效。
但是我会更改URI。 /channels
看起来像集合资源URI。我希望它的子节点是频道,例如/channels/kron4
(你可以使用任何唯一的字符串,而不是jsut ID来识别实例资源)。
因此,/channels/on_now
看起来很奇怪。它看起来像一个名为“on_now”的频道。虽然没有什么可以阻止您使用它,但它可能会与 称为“On Now”的频道冲突! 我只会使用/on_now
作为您的URI。 /channels/kron4/on_now
显然也适用于单个频道的响应。
答案 2 :(得分:1)
/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
的节目! :)。
答案 3 :(得分:1)
只需附上上述答案:
/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访问权限,那么您可以做出这样的好事({3}}
根据我的说法,需要更多的数据,api就像这样: ?// EPG时间=安培;开始= 0&安培;极限= 1&安培;持续时间=
这将定义一个通用api,以根据时间和持续时间获取基于位置的tv_listing信息。结果将在给定时间跨度内发生的频道列表之间的所有节目中分页。
答案 4 :(得分:1)
我不是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/
路径内。
那是因为如果你只是回归节目,另一种方法是/shows/?filter=on_now
。
你可以:
/shows/?filters=on_now&channel=bbc
我喜欢将资源视为我回归的“事物”,而不仅仅是关系的标准思维。图中的底层对于属性是很好的,对于“其他事物”的收集不太确定。
按照相同的示例,我宁愿使用/channels/{channel-id}/program
代替/channels/{channel-id}/shows