API 版本管理是后端开发中一个棘手但又无法回避的问题,尤其是在移动端开发中更为明显。现在,SpringBoot4.0 为 SpringMVC 和 WebFlux 提供了原生的 API 版本控制支持。
SpringBoot4.0支持版本控制策略包含:
请求头版本控制:通过自定义请求头来指定版本
URI版本控制:在URL路径中添加版本,比如
/api/v1/orders查询参数版本控制:通过查询参数指定版本,比如
/api/orders?version=1媒体类型版本控制:通过媒体类型来指定版本策略,比如:
Accept: application/json;version=1自定义版本控制:需要实现
ApiVersionResolve接口
请求头版本控制
@RestController
@RequestMapping("/api")
public class VersionInHeaderController {
@GetMapping(version = "v1", path = "/demo")
public String v1(){
return "v1";
}
@GetMapping(version = "v2", path = "/demo")
public String v2(){
return "v2";
}
}
两个接口的路径是相同的,但是版本号不一样,只需添加配置类:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer.useRequestHeader("X-API-VERSION");
}
}
或者添加配置项:
spring:
mvc
apiversion:
use:
header: X-API-VERSION
此时只要在调用接口的时候传递请求头X-API-VERSION=v1或者X-API-VERSION=v2即可切换要调用的接口
curl 'http://localhost:8080/api/demo' -H 'X-API-VERSION: v1'
curl 'http://localhost:8080/api/demo' -H 'X-API-VERSION: v2'
URI版本控制
@RestController
@RequestMapping("/api/{version}")
public class VersionInPathController {
@GetMapping(version = "v1", path = "/demo")
public String v1(){
return "v1";
}
@GetMapping(version = "v2", path = "/demo")
public String v2(){
return "v2";
}
}
跟上面的代码几乎相同,区别在于请求的url种添加了{version}前缀,同样需要添加配置类:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
//1说明是uri中的第一个部分
configurer.usePathSegment(1);
}
}
或者添加配置项:
spring:
mvc:
apiversion:
use:
pathSegment: 1
此时只要在调用接口的时候设置版本号即可:
curl 'http://localhost:8080/api/v1/demo'
curl 'http://localhost:8080/api/v2/demo'
查询参数版本控制
@RestController
@RequestMapping("/api")
public class VersionInQueryController {
@GetMapping(version = "v1", path = "/demo")
public String v1(){
return "v1";
}
@GetMapping(version = "v2", path = "/demo")
public String v2(){
return "v2";
}
}
同样的接口,还是需要添加配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer.useQueryParam("X-API-VERSION");
}
}
或者添加配置项:
spring:
mvc:
apiversion:
use:
queryParameter: X-API-VERSION
此时需要在查询参数中传递X-API-VERSION参数,比如:
curl 'http://localhost:8080/api/demo?X-API-VERSION=v1'
curl 'http://localhost:8080/api/demo?X-API-VERSION=v2'
媒体类型版本控制
@RestController
@RequestMapping("/api")
public class VersionInMediaTypeController {
@GetMapping(version = "v1", path = "/demo")
public String v1(){
return "v1";
}
@GetMapping(version = "v2", path = "/demo")
public String v2(){
return "v2";
}
}
此时需要添加配置类:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer.useMediaTypeParameter(MediaType.APPLICATION_JSON, "X-API-VERSION");
}
}
或者添加配置项:
spring:
mvc:
apiversion:
use:
mediaTypeParameter:
"[application/json]": "X-API-VERSION"
调用的时候需要在Accept头或者Content-Type头中传递X-API-VERSION,Accept的优先级更高,比如:
curl localhost:8080/api/demo -H 'Accept: application/json; X-API-VERSION=v1'
curl localhost:8080/api/demo -H 'Accept: application/json; X-API-VERSION=v2'
自定义版本控制
此时需要我们在配置类中添加一个实现了ApiVersionResolver接口的实现类,利用它来实现版本的获取,这种方式可以非常灵活。
比如我们想实现优先根据请求头,如果不存在则使用查询参数来获取版本号,那么可以这么实现:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer.useVersionResolver(
request -> {
String headerVersion = request.getHeader("X-API-VERSION");
if (headerVersion != null && headerVersion.length() > 0) {
return headerVersion;
}
String parameterVersion = request.getParameter("X-API-VERSION");
if (parameterVersion != null && parameterVersion.length() > 0) {
return parameterVersion;
}
return "v1";
});
}
}
源码下载:源码
更多SpringBoot4.0新特性请参考:SpringBoot4.0新特性