2

想象一个 API,它为一个电视节目表应用程序(如zap2it 电视节目表)返回 JSON 数据。

它基本上是一个电视频道列表,以及每个频道当前和以后的节目。目前,我有一个返回所有通道的 API GET /channels。但是,需要为该数据中的每个频道添加当前正在播放的节目。我正在考虑添加一个新的 API,GET /channels/on_now以将其与当前的 API 区分开来。我想为新的 API 明确这一点,我不想为每个频道单独调用,需要为所有频道返回当前显示数据。这是一个好的 REST API 设计吗?

当前GET /channelsJSON 数据

[
   "channel": {
      "channelName": "KRON4",
    },
   "channel": {
      "channelName": "KTOV5",
    },
   ...
]

GET /channels/on_now以下新 API 的预期 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...
]
4

5 回答 5

3

我建议专注于内容,而不是 URL。

示例:您有一个入口点,'/'。这是 API 中唯一的 URL。GET 就返回 st like

{
    "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评论后编辑:

您可以引入“嵌入”参数以限制请求数量:

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"
}
于 2012-06-04T23:09:07.957 回答
2

您问:

这是一个好的 REST API 设计吗?

的,是的。

与回答的其他人相反,您可以自由定义任何您想要的资源,只要它代表一个名词。这包括与时间相关的服务,例如“现在电视上有什么节目”或 perrenial 示例,“<city> 的当前天气”。这些服务资源与代表节目或频道的更多静态资源一样有效。

但是,我会更改 URI。/channels看起来像一个集合资源 URI。我希望它的孩子是频道,例如/channels/kron4(您可以使用任何唯一的字符串,而不是 ID,来识别实例资源)。
因此,/channels/on_now看起来很奇怪。它看起来像一个名为“on_now”的频道。虽然没有什么可以阻止您使用它,但它可能会在以后与一个名为“On Now”的频道发生冲突我会简单地/on_now用作您的 URI。 /channels/kron4/on_now显然也有利于单通道的响应。

于 2012-12-05T12:30:28.460 回答
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 访问https://developer.sdp.nds.com/page/about ,那么您可以很好地开始做这样的事情

按照我的说法,需要更多数据,api 会是这样的: //epg?time=&start=0&limit=1&duration=

这将定义一个通用 api,以根据时间和持续时间获取基于位置的 tv_listing 信息。结果将与在给定时间跨度内发生的频道列表之间的所有节目进行分页。

于 2012-06-04T23:05:31.883 回答
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您的任何频道!:) 。

于 2012-06-04T21:50:11.287 回答
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

于 2014-01-10T01:22:13.467 回答