Web服务REST API版本控制是否有任何已知的方法或最佳实践?
我注意到AWS通过端点的URL进行版本控制.这是唯一的方法还是有其他方法来实现同一目标?如果有多种方式,每种方式的优点是什么?
我一直在寻找如何使用Spring 3.2.x管理REST API版本,但我找不到任何易于维护的东西.我先解释一下我遇到的问题,然后解决一个问题...但我想知道我是否在这里重新发明了这个问题.
我想基于Accept标头管理版本,例如,如果请求具有Accept标头application/vnd.company.app-1.1+json,我希望spring MVC将此转发给处理此版本的方法.并且由于并非API中的所有方法都在同一版本中发生更改,因此我不希望转到每个控制器并更改任何版本之间未更改的处理程序.我也不想有逻辑来确定控制器本身使用哪个版本(使用服务定位器),因为Spring已经发现了要调用的方法.
因此,采用版本1.0到1.8的API,其中版本1.0中引入了处理程序并在v1.7中进行了修改,我希望以下列方式处理它.想象一下,代码在控制器内部,并且有一些代码能够从头部中提取版本.(以下在Spring中无效)
@RequestMapping(...)
@VersionRange(1.0,1.6)
@ResponseBody
public Object method1() {
// so something
return object;
}
@RequestMapping(...) //same Request mapping annotation
@VersionRange(1.7)
@ResponseBody
public Object method2() {
// so something
return object;
}
Run Code Online (Sandbox Code Playgroud)
这在春天是不可能的,因为2个方法具有相同的RequestMapping注释并且Spring无法加载.这个想法是VersionRange注释可以定义一个开放或封闭的版本范围.第一种方法从版本1.0到1.6有效,而第二种方法从版本1.7开始(包括最新版本1.8).我知道如果有人决定通过99.99版本,这种方法会中断,但这是我可以忍受的.
现在,由于上面的内容是不可能的,如果没有对Spring的工作方式进行认真的修改,我就会考虑修改处理程序与请求匹配的方式,特别是编写我自己的方式ProducesRequestCondition,并在那里有版本范围.例如
码:
@RequestMapping(..., produces = "application/vnd.company.app-[1.0-1.6]+json)
@ResponseBody
public Object method1() {
// so something
return object;
}
@RequestMapping(..., produces = "application/vnd.company.app-[1.7-]+json)
@ResponseBody
public Object method2() {
// so something
return object;
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我可以在注释的产生部分中定义关闭或打开的版本范围.我工作的这个解决方案现在,随着我仍然不得不更换一些核心Spring MVC类(的问题RequestMappingInfoHandlerMapping …
我看了一下API版本的最佳实践?,但我不太相信答案,所以我再次用更具体的例子质疑版本控制部分.我有两个URI(一个版本作为URI的一部分,一个没有):
http://xxxx/v1/user/123 -> favored solution in discussed thread
http://xxxx/user/123
Run Code Online (Sandbox Code Playgroud)
我怀疑第一个链接是否表达了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
Run Code Online (Sandbox Code Playgroud)
人们还可以争辩说,这样的版本内容协商可能是路径中URI的一部分,但我觉得它反直觉,因为你最终可能会为同一资源使用不同的URI,并且必须在某些时候维护重定向.
总结:在REST URI中,没有api版本,只有资源表示的版本控制.表示版本信息属于内容协商(作为queryParam或HTTP'接受').
你怎么看?你不同意/同意哪些事情?
我已经阅读了许多关于版本化RESTful服务的Stack Overflow(和其他)帖子.说实话,这有点压倒性的.
我决定对我们的(边缘)RESTful服务使用Accept:标头,以便客户端可以请求特定版本的资源.我不清楚的是在Accept标头中指定的内容.
我经常看到的例子是这样的:
Accept: application/vnd.mycompany.myapp.customer-v2+json
Run Code Online (Sandbox Code Playgroud)
我的问题是:
我是否正确所有vnd类型必须注册?(http://www.iana.org/cgi-bin/mediatypes.pl)
版本和类型(即-v2 + json)是该类型的一部分,因此需要注册每个版本和类型吗?
是否有任何理由使用vnd而不是不需要注册的"x-"子类型?例如:
Accept: application/x-mycompany.myapp-v2+json
Run Code Online (Sandbox Code Playgroud)
现有的API仅供内部使用,但将来会向客户展示.
不确定这是否有意义,但可以使用现有类型但添加版本吗?(当前API返回"application/json")
Accept: application/json-v2
Run Code Online (Sandbox Code Playgroud)附加版本和类型的可接受格式是什么(例如-v2 + json).
如果客户端要求提供不受支持的版本,该怎么办?406是正确答案吗?客户可以请求任何版本吗?或者更一般地说,如果客户端不提供Accept标头或Accept:*/*,该怎么办?
任何其他建议欢迎.当然,目标是允许更改服务为给定资源返回的内容,但不会破坏现有客户端.
这是我最近查看过的一小部分资源:
我在http://example.com/v1/SomeResource上部署了RESTful Web服务.有一天,新的协议版本(不向后兼容)被部署到http://example.com/v2/SomeResource.从客户端看,此升级可能在两个HTTP请求之间的任何时间发生.
服务器如何向客户端指示它不再支持v1调用,并且客户端应该升级到v2?我可以使用适当的响应代码吗?
我想向客户提供以下信息:
我正在为Web应用程序设计REST API.我想清楚地对API进行版本化,以便将来可以更改界面而不会破坏现有服务.因此,在我的v1.0 API中,我希望将其清楚地标识为v1.0 API,让我可以自由地发布未来的v1.1版本并进行重大更改.
我的问题是,URI的路径组件中的一段时间是不好的做法?
例如.有没有什么好的理由不使用http://example.com/myapi/v1.0/services作为我服务的URI?
我正在设计RESTful API.结果将采用JSON对象的形式.我不需要将我的POJO类中的所有字段发送到客户端,因此我应该定义某种"合同".
假设我有一个Property类,我为它定义了id,name和address.后来,我可能想要在不影响客户端的情况下将地址更改为geoData.
有没有一些优雅的方式(模式)来做到这一点?
rest ×7
versioning ×4
api ×2
java ×2
api-design ×1
mime-types ×1
spring ×1
spring-mvc ×1
uri ×1