SpringBoot4新特性-API版本管理实践

47 阅读5分钟

Spring Boot 4 增加一些新特性,API版本管理是其中的一项,让 API 变更更加丝滑。 无效在自己设计版本管理。

API接口版本控制是应用开发中的关键实践,允许开发者在不破坏现有客户端的情况下管理 API 的变更。Spring Boot 4 引入了对 API 版本控制的原生支持,为服务器端和客户端应用程序提供了强大的工具,以高效处理版本特定的路由和请求。

API版本控制作用:

API 版本控制允许开发者在 API 迭代过程中引入新功能、修复错误,性能优化,并行开发。同时确保向后兼容性,服务连续性。

常见的版本控制策略包括:

  • URI 版本控制:在 URL 路径中包含版本号,例如 /api/v1/orders, /api/v2/orders
  • 请求头版本控制:通过请求头(如自定义 version 头)指定版本,例如 version=1.1
  • 查询参数版本控制:通过查询参数传递版本号,例如 /api/orders?version=1。
  • 媒体类型:application/vnd.company.app-v1+json, application/vnd.company.app-v2+json

Spring Boot4 为Web 应用程序引入了 API 版本控制支持,允许通过 @RequestMapping 注解中的version属性将请求映射到不同的控制器方法。这种方法简化了多版本 API 的管理,使开发者能够在一个应用程序中处理多个 API 版本。

以下注解,同样增加了version属性

  • @GetMapping,
  • @PostMapping,
  • @PutMapping,
  • @DeleteMapping,
  • @PatchMapping

SpringBoot4的starter 不同于 4之前的版本。 SpringBoot4 的Web依赖名称: spring-boot-starter-webmvc 相关的依赖如下:

webmvc-starter.png

依赖重新整理,命名。 对比Spring Boot 3的 Web模块依赖

web-starter-v3.png

对比能看到变化 1.json的依赖 版本4 是spring-boot-starter-jackson , 版本3的spring-boot-starter-json 2.版本4里面, 单独的事spring-boot-http-converter ,版本3中没有这个依赖 3.版本3中的spring-web依赖, 放在了版本4的 spring-boot-http-converter的里面了

1.1 请求头版本控制

需求:

自定义请求header表示版本信息。 例如 请求header名称: X-API-VERSION , 版本信息如 X-API-VERSION=1.0 , X-API-VERSION=2.0

使用@RequestMapping (version=”1.0“) , @RequestMapping (version="2.0") 定义两个方法,处理两个版本的请求

编码:

订单数据类:

 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 public class Order {
     private String id;
     private String name;
 }
 ​

控制器类ScmController

 @RestController
 public class ScmController {
 ​
     @RequestMapping(value = "/orders",version = "1.0")
     public ResponseEntity<Order> listOrdersByV1(){
         Order order = new Order("A001","杭州3日自由行");
         return ResponseEntity.ok(order);
     }
 ​
     @RequestMapping(value = "/orders",version = "2.0")
     public ResponseEntity<Order> listOrdersByV2(){
         Order order = new Order("A002","15日游轮欧洲游AA");
         return ResponseEntity.ok(order);
     }
 }

SpringMVC配置类,设置版本控制参数

 @Configuration
 public class WebMvcConfig  implements WebMvcConfigurer {
     @Override
     public void configureApiVersioning(ApiVersionConfigurer configurer) {
        configurer.useRequestHeader("X-API-VERSION");
     }
 }

configurer.useRequestHeader( 请求header名称) , 以此名称作为版本号的标志。

接口测试 version-header.png

1.2 请求路径参数版本控制

请求url路径包含version, 例如/api/v1/orders , /api/v2/orders

主要设置ApiVersionConfigurer对象usePathSegment(index)方法

 configurer.usePathSegment(index);

index——要检查的路径段的索引;例如,对于像“/{version}/…”这样的URL,使用索引0,对于“/api/{version]/…”,使用索引1。

修改Controller

 @RestController
 public class ScmController {
 ​
     @RequestMapping(value = "/api/{version}/orders",version = "v1")
     public ResponseEntity<Order> listOrdersByV1(){
         Order order = new Order("A001","杭州3日自由行");
         return ResponseEntity.ok(order);
     }
 ​
     @RequestMapping(value = "/api/{version}/orders",version = "v2")
     public ResponseEntity<Order> listOrdersByV2(){
         Order order = new Order("A002","15日游轮欧洲游AA");
         return ResponseEntity.ok(order);
     }
 }

${version} : 自定义路径变量 , 名称自定义

访问接口的URL 类似 http://ip:port/api/v1/orders

SpringMVC配置类,设置版本控制参数-路径片段

 @Configuration
 public class WebMvcConfig  implements WebMvcConfigurer {
     @Override
     public void configureApiVersioning(ApiVersionConfigurer configurer) {
         //路径包含版本参数
         configurer.usePathSegment(1);
     }
 }

测试接口:Postman

version-path.png

1.3 请求参数版本控制

请求包含版本控制参数 ,例如ver=v1 , ver=v2

控制器定义

 @RestController
 public class ScmController {
 ​
     @RequestMapping(value = "/api/orders",version = "v1")
     public ResponseEntity<Order> listOrdersByV1(){
         Order order = new Order("A001","杭州3日自由行");
         return ResponseEntity.ok(order);
     }
 ​
     @RequestMapping(value = "/api/orders",version = "v2")
     public ResponseEntity<Order> listOrdersByV2(){
         Order order = new Order("A002","15日游轮欧洲游AA");
         return ResponseEntity.ok(order);
     }
 }

SpringMVC配置类,设置版本控制参数-路径片段

 @Configuration
 public class WebMvcConfig  implements WebMvcConfigurer {
     @Override
     public void configureApiVersioning(ApiVersionConfigurer configurer) {
         //请求参数ver表示版本参数
         configurer.useQueryParam("ver");
     }
 }

测试接口,Postman

version-param.png

总结

SpringBoot4的版本控制功能, 实际是Spring Framework 7.0 提供的新特性。版本解析机制支持多种策略。例如,开发者可以从自定义请求头或查询参数中提取版本信息。这种灵活性使得 Spring Framework 7.0 能够适应不同的版本控制需求,从简单的 URI 版本控制到复杂的基于内容的协商。

策略描述优点缺点
URI 版本控制在 URL 路径中包含版本号(如 /api/v1/users简单直观,易于在浏览器中测试可能导致 URL 路径过长,难以维护
请求头版本控制通过请求头指定版本(如 X-API-VERSION 头)保持 URL 简洁,适合复杂版本控制需要客户端支持自定义头,调试较复杂
查询参数版本控制通过查询参数传递版本号(如 /api/orders?ver=1实现简单,URL 结构清晰不够语义化,可能影响缓存策略
内容协商版本控制基于 Accept 头的媒体类型确定版本灵活,符合 REST 原则实现复杂,客户端配置要求较高

SpringBoot 版本控制功能主要由几个核心类实现,下面我们对其中几个关键类进行深入分析。

ApiVersionResolver 接口 ApiVersionResolver 是一个函数式接口,定义了从请求中解析版本的方法。

 @FunctionalInterface
 public
 interface ApiVersionResolver {
 ​
     /**
      * Resolve the version for the given request.
      * @param request the current request
      * @return the version value, or {@code null} if not found
      */
     @Nullable String resolveVersion(HttpServletRequest request);
 ​
 }

这个接口允许开发者实现自定义的版本解析策略,从请求中提取版本信息。

实现类目前有3个

QueryApiVersionResolver: 从请求参数中获取版本信息

PathApiVersionResolver:从请求路径中获取版本信息 。例如 /api/v1/order, /api/v2/order

MediaTypeParamApiVersionResolver: 从请求的Accept 或 Content-Type 获取媒体类型,作为版本信息