spring MVC 控制器版本控制
spring MVC controller versioning
我有一个 spring 引导应用程序,它有一个 spring MVC 控制器。我正在尝试使用 Accept header.
对其余 api 进行版本控制
下面是我的控制器的样子
RestController
@RequestMapping(value = "/private/")
public class AppleController {
private final AppleService appleService;
public AppleController(AppleService appleService) {
this.appleService = appleService;
}
@GetMapping(value = "apples/{id}", produces = "application/json; v=1.0",
headers = "Accept=application/json; v=1.0")
public ResponseEntity getByappleId(@PathVariable("id") Long appleId) {
System.out.println("version1");
GetByappleIdResponse response = appleService.findByappleId(appleId);
return new ResponseEntity<>(response, HttpStatus.OK);
}
@GetMapping(value = "apples/{id}", produces = "application/json; v=2.0",
headers = "Accept=application/json; v=2.0")
public ResponseEntity getByappleId2(@PathVariable("id") Long appleId) {
System.out.println("version2");
GetByappleIdResponse response = appleService.findByappleId2(appleId);
return new ResponseEntity<>(response, HttpStatus.OK);
}
无论我在调用 API 时在 Accept header 中传递的版本如何,总是调用 "getByappleId" 方法,因此仅返回版本 1 响应。
我的控制器有什么问题吗?
有很多选项可以实现 REST 的版本控制 API:
- 在评论中建议手动路由您的请求;
将版本作为您接受 header 值的一部分,f.e.:
(headers = "Accept=application/vnd.name.v1+json")
(headers = "Accept=application/vnd.name.v2+json")
将版本作为映射的一部分:
@GetMapping("apples/v1/{id})"
@GetMapping("apples/v2/{id})
所以你需要决定走哪条路。一些有用的链接:
如本回答所述:https://whosebug.com/a/34427044/258813(并在评论中提到)Spring 不支持使用 header 那样的路由。
如果你想通过版本 header 支持路由,我会推荐自定义路由条件和注释 - 当然,如果你正在构建一个大的 API,它会导致更少的代码和更优雅的解决方案。
您可以定义一些注解,例如 @ApiVersion(1)
,您可以将其添加到也是请求映射的任何方法,然后添加自定义路由条件,它会正常运行。
我在此处描述了使用自定义路由条件和注释(基于子域 - 但可以轻松切换为检查 headers):http://automateddeveloper.blogspot.co.uk/2014/12/spring-mvc-custom-routing-conditions.html
我有一个 spring 引导应用程序,它有一个 spring MVC 控制器。我正在尝试使用 Accept header.
对其余 api 进行版本控制下面是我的控制器的样子
RestController
@RequestMapping(value = "/private/")
public class AppleController {
private final AppleService appleService;
public AppleController(AppleService appleService) {
this.appleService = appleService;
}
@GetMapping(value = "apples/{id}", produces = "application/json; v=1.0",
headers = "Accept=application/json; v=1.0")
public ResponseEntity getByappleId(@PathVariable("id") Long appleId) {
System.out.println("version1");
GetByappleIdResponse response = appleService.findByappleId(appleId);
return new ResponseEntity<>(response, HttpStatus.OK);
}
@GetMapping(value = "apples/{id}", produces = "application/json; v=2.0",
headers = "Accept=application/json; v=2.0")
public ResponseEntity getByappleId2(@PathVariable("id") Long appleId) {
System.out.println("version2");
GetByappleIdResponse response = appleService.findByappleId2(appleId);
return new ResponseEntity<>(response, HttpStatus.OK);
}
无论我在调用 API 时在 Accept header 中传递的版本如何,总是调用 "getByappleId" 方法,因此仅返回版本 1 响应。
我的控制器有什么问题吗?
有很多选项可以实现 REST 的版本控制 API:
- 在评论中建议手动路由您的请求;
将版本作为您接受 header 值的一部分,f.e.:
(headers = "Accept=application/vnd.name.v1+json")
(headers = "Accept=application/vnd.name.v2+json")
将版本作为映射的一部分:
@GetMapping("apples/v1/{id})"
@GetMapping("apples/v2/{id})
所以你需要决定走哪条路。一些有用的链接:
如本回答所述:https://whosebug.com/a/34427044/258813(并在评论中提到)Spring 不支持使用 header 那样的路由。
如果你想通过版本 header 支持路由,我会推荐自定义路由条件和注释 - 当然,如果你正在构建一个大的 API,它会导致更少的代码和更优雅的解决方案。
您可以定义一些注解,例如 @ApiVersion(1)
,您可以将其添加到也是请求映射的任何方法,然后添加自定义路由条件,它会正常运行。
我在此处描述了使用自定义路由条件和注释(基于子域 - 但可以轻松切换为检查 headers):http://automateddeveloper.blogspot.co.uk/2014/12/spring-mvc-custom-routing-conditions.html