我看了一下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'接受')。
你怎么看?你不同意/同意哪些事情?答案 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版。
我不确定。我想你有几个选择:
一般来说,我认为您希望优化您的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,因为次要、补丁等向后兼容。