Swagger相同Tag下如何按控制器分组端点并保持HTTP方法顺序
实现方案
是可以实现同Tag下按控制器分组、同时保留控制器内部方法顺序的需求的,目前主流的Swagger实现(SpringDoc、Springfox)都支持自定义操作排序逻辑,以下是具体操作步骤:
方案1:手动配置方法排序(简单快速)
直接在接口方法上添加@Operation注解指定排序值,给v1控制器的所有方法设置小的排序值,v2控制器的方法设置大的排序值即可:
@RequestMapping("/v1") @Tag(name = "controller") public class ControllerV1 { @Operation(order = 1) @GetMapping public String v1Get(){} @Operation(order = 2) @PutMapping public String v1Put(){} }
@RequestMapping("/v2") @Tag(name = "controller") public class ControllerV2 { @Operation(order = 101) @GetMapping public String v2Get(){} @Operation(order = 102) @PutMapping public String v2Put(){} }
之后在配置文件中开启操作按order排序即可,以SpringDoc为例:
springdoc: swagger-ui: operations-sorter: order
方案2:自动分配排序偏移(无需逐个方法配置)
如果接口数量多,可以写全局自定义处理器,自动按控制器的版本前缀给所有方法加排序偏移,不需要每个方法手动写order:
import org.springdoc.core.customizers.OperationCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.method.HandlerMethod; @Configuration public class SwaggerConfig { @Bean public OperationCustomizer versionOperationCustomizer() { return (operation, handlerMethod) -> { Class<?> controllerClazz = handlerMethod.getBeanType(); RequestMapping mapping = controllerClazz.getAnnotation(RequestMapping.class); if (mapping != null && mapping.path().length > 0) { String prefix = mapping.path()[0]; // 按版本号加排序偏移,100的间隔足够容纳单个控制器的所有方法 if (prefix.startsWith("/v1")) operation.setOrder(operation.getOrder() + 100); if (prefix.startsWith("/v2")) operation.setOrder(operation.getOrder() + 200); } return operation; }; } }
配置后只需保证单个控制器内部的方法@Operation order按需求从小到大设置即可,不同版本的接口会自动分组排序,最终展示效果和你预期的完全一致:
- v1 GET
- v1 PUT
- v2 GET
- v2 PUT
Springfox适配方案
如果你使用的是停更的Springfox 2.x/3.x版本,逻辑完全一致,只需将自定义配置替换为OperationBuilderPlugin的实现类即可。
内容的提问来源于stack exchange,提问作者Jornwer
相关产品推荐
相关产品推荐

