如何使用 spring 管理 REST API 版本控制?
我一直在搜索如何使用Spring 3.2.x管理REST API版本,但我没有找到任何易于维护的东西。我将首先解释我遇到的问题,然后解释一个解决方案...但我确实想知道我是否在这里重新发明了轮子。
我想基于 Accept 标头管理版本,例如,如果请求具有 Accept 标头,我希望 spring MVC 将其转发到处理此版本的方法。而且,由于并非 API 中的所有方法都在同一版本中更改,因此我不想转到我的每个控制器,并为版本之间未更改的处理程序更改任何内容。我也不想有逻辑来弄清楚在控制器本身中使用哪个版本(使用服务定位器),因为Spring已经发现了要调用的方法。application/vnd.company.app-1.1+json
因此,将版本为1.0的API带到1.8,其中在1.0版本中引入了处理程序并在v1.7中进行了修改,我希望通过以下方式处理它。想象一下,代码位于控制器内部,并且有一些代码能够从标头中提取版本。(以下内容在春季无效)
@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;
}
这在Spring中是不可能的,因为2种方法具有相同的注释并且Spring无法加载。这个想法是注释可以定义开放或关闭的版本范围。第一种方法在版本 1.0 到 1.6 之间有效,而第二种方法适用于版本 1.7 及更高版本(包括最新版本 1.8)。我知道如果有人决定通过版本99.99,这种方法会中断,但这是我可以忍受的。RequestMapping
VersionRange
现在,由于如果不对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;
}
通过这种方式,我可以在注释的 produce 部分定义封闭或开放版本范围。我现在正在研究这个解决方案,但问题是我仍然必须替换一些核心的Spring MVC类(和),我不喜欢,因为每当我决定升级到较新版本的spring时,这意味着额外的工作。RequestMappingInfoHandlerMapping
RequestMappingHandlerMapping
RequestMappingInfo
我将不胜感激任何想法...特别是,任何建议都以更简单,更易于维护的方式执行此操作。
编辑
添加赏金。要获得赏金,请回答上面的问题,而不是建议在控制器本身中采用此逻辑。Spring已经有很多逻辑来选择要调用的控制器方法,我想借用它。
编辑 2
我在github中分享了原始的POC(有一些改进):https://github.com/augusto/restVersioning