繁体   English   中英

用于访问多个资源的API的REST设计

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM