REST api版本控制(仅表示表示,而不是资源本身)

时间:2010-01-07 23:58:15

标签: rest versioning api-design

我看了一下Best practices for API versioning?,但我不太相信答案,所以我再次用一个更具体的例子来质疑版本控制部分。我有两个URI(一个是版本控制作为URI的一部分而另一个没有):

http://xxxx/v1/user/123    -> favored solution in discussed thread
http://xxxx/user/123             

我怀疑第一个链接是否表达了REST的想法。我发现http://xxxx/v1/user/123令人困惑,因为它表明某天会有更高的api版本,如http://xxxx/v2/user/123。但这在REST术语中没有意义,api版本本身是HTTP 1.0或1.1,它已经在HTTP请求中发送。这个以REST资源为中心的视图与其他api接口(如SOAP或Java接口)非常不同(通常在限定名称中使用api版本)。

在REST中,版本控制唯一有意义的是该资源的表示(例如添加或删除新字段)。此版本控制属于内容协商的部分,如:

http://xxx/user/123 + HTTP 'Accept' Header -> Content negotation through header
http://xxx/user/123?v=1                    -> for perma-links/hyperlinks

还有人可能会争辩说,这样的版本内容协商可能是路径中URI的一部分,但我觉得它反直觉,因为你可能最终得到同一资源的不同URI,并且必须保持重定向到某点。

总结:在REST URI中,没有api版本,只有资源表示的版本控制。表示版本信息属于内容协商(作为queryParam或HTTP'接受')。

你怎么看?你不同意/同意哪些事情?

8 个答案:

答案 0 :(得分:36)

我完全同意; URI表示标识,引入新版本时标识不会更改。当然,可能有新的URI用于其他概念,现有的URI可能会重定向......但是在URI中包含“v2”会让我感到厌恶。

请注意,这与REST无关,实际上,从REST角度来看,它只是字符。

答案 1 :(得分:10)

可以侦听X-API-Version HTTP请求标头。如果标头存在,则服务器必须使用该版本的API。如果标头不存在,服务器可能会使用最新版本的API。

> GET /user/123 HTTP/1.1
> Host: xxx
> X-API-Version: >=1.5.1, <2.0.0
> Accept: application/json
>

< HTTP/1.1 200 OK
< X-API-Version: 1.6.12
<
< { "user": { "id": 123, "name": "Bob Smith" } }
<

答案 2 :(得分:9)

对于它的价值,我同意你的观点Manuel。你可以在这个问题How to version REST URIs

中看到我的推理

有很多人似乎不同意但我不担心。只要您尊重超文本约束,您的网址看起来真的不会对您的客户产生太大影响。

答案 3 :(得分:2)

我同意您不希望在API中显示的资源的URI中看到版本。这使他们不“酷”。同意它是最有可能改变的表示。

然而,它确实提出了更改特定表示的内容时会发生什么的问题。例如,如果你的frobnitz的原始JSON表示是

{"x": "bam", "y": "hello"}

并且您想要添加一个“z”字段,您可能会觉得客户端应该知道我们现在处于某种数据方案的第2版。

我不确定。我想你有几个选择:

  • 让您的客户在面对轻微变化的表现时保持灵活性。在上面的例子中,我们仍然在生成一个JSON字典。
  • 如果必须,请在表示中放置一个版本(本例中为版本字段)。通过这样做,您可以有效地声明JSON内容类型中的子表示。我认为这是非常有限的。
  • 使用您自己的MIME类型并对其进行版本化:application / x-my-special-json1.0,application / x-my-special-json1.1。这允许您相互独立地对表示进行版本控制。再一次,有了这个,你就会向你的客户提出重要的要求,知道发生了什么。

一般来说,我认为您希望优化您的API以及您自己没有发明的客户的代表;其他人在发现你的资源时会创造的。我相信这是有用的,即使你正在制作私有的东西,因为它构建了一个有用的设计约束,有助于使你的系统更健壮。

答案 4 :(得分:1)

  

我找到http://xxxx/v1/user/123   令人困惑,因为它暗示那里   总有一天将是一个更高的api版本   比如http://xxxx/v2/user/123

这并不意味着 - 但是你将来有这种能力。

  

但这在REST中没有意义   术语,api版本本身就是HTTP   1.0或1.1,已在HTTP请求中发送。

您的API版本和用于发出请求的HTTP版本不必相同。

  

人们也可以争辩说这样的版本   内容谈判可能是其中的一部分   路径中的URI,但我发现它   反直觉,因为你可以   最终使用不同的URI   相同的资源,必须维护   在某些时候重定向。

可以将版本作为URI参数进行演示。

  
    

http://xxx/user/123?v=1 - &gt; for perma-links / hyperlinks

  

答案 5 :(得分:1)

另一种方法可能是“一个表示有多个API”:

http://xxx/user/123/api/1.json

如果您愿意,可以在请求时使用最新的API返回表示:

http://xxx/user/123.json

就个人而言,我更喜欢其他解决方案,但这是另一种我尚未见过的方法。

答案 6 :(得分:0)

对于REST,大多数答案忘记的是数据元素。我假设多个版本API仍然共享相同的数据层。这意味着数据层会强制您以向后兼容的方式进行思考。只有在API以向后兼容的方式进行更改时,才能实现必须进行的重大更改。实际上,这意味着在API文档中按日期使用弃用以指示何时删除某些内容时,会向您的实体静默添加其他属性。理想情况下,您使用注册方案和API密钥用户的电子邮件地址,因此您可以通知他们在特定范围内的弃用(Facebook)。因此,我认为您不需要在任何地方指定版本。

答案 7 :(得分:0)

API 可以被视为顶级资源,/apis/v1/users/,那么在 URI 中包含版本号绝对没有问题。对于 Semver,只有主要版本进入 URI,因为次要、补丁等向后兼容。