如何基于配置条件在springdoc-openapi中隐藏指定接口方法
springdoc-openapi 基于配置控制单个接口显隐的实现方案
springdoc-openapi 完全支持接口扫描后的自定义过滤能力,常用的实现方案有两种,可根据实际需求选择:
方案1:仅在swagger文档中隐藏接口,不影响接口本身调用
通过实现OpenApiCustomiser全局过滤器,结合配置属性动态过滤不需要展示的接口,有两种使用形式:
形式A:配合自定义注解精准控制单个接口
- 第一步:自定义注解标记需要控制显隐的接口
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ApiDisplay { // 对应配置文件中的开关key String configKey(); // 配置为空时默认是否展示 boolean defaultShow() default false; }
- 第二步:实现全局过滤器,读取配置动态过滤接口
@Component public class ApiDisplayFilter implements OpenApiCustomiser { private final Environment env; public ApiDisplayFilter(Environment env) { this.env = env; } @Override public void customise(OpenAPI openApi) { openApi.getPaths().entrySet().removeIf(entry -> { PathItem pathItem = entry.getValue(); // 校验当前路径下所有请求方法是否全部需要隐藏 return Stream.of(pathItem.getGet(), pathItem.getPost(), pathItem.getPut(), pathItem.getDelete(), pathItem.getPatch()) .filter(Objects::nonNull) .allMatch(operation -> { ApiDisplay annotation = operation.getOperationContext().getMethod().getAnnotation(ApiDisplay.class); if (annotation == null) { // 未加注解的接口默认展示 return false; } // 读取配置判断是否隐藏 return !env.getProperty(annotation.configKey(), Boolean.class, annotation.defaultShow()); }); }); } }
- 第三步:在需要控制的接口上添加注解即可
@RestController @RequestMapping("/api/user") public class UserController { // 普通接口默认展示 @GetMapping("/list") public List<User> list() { // 业务逻辑 } // 测试接口仅在配置api.test.show=true时才在文档展示 @ApiDisplay(configKey = "api.test.show", defaultShow = false) @PostMapping("/test/add") public void testAdd() { // 测试逻辑 } }
形式B:无需注解,直接配置路径批量隐藏
- 第一步:在配置文件中添加需要隐藏的路径规则
springdoc: hidden: paths: /api/test/**,/api/internal/**
- 第二步:实现过滤器匹配路径过滤
@Component @ConfigurationProperties(prefix = "springdoc.hidden") public class PathHideFilter implements OpenApiCustomiser { private final AntPathMatcher pathMatcher = new AntPathMatcher(); private List<String> paths = new ArrayList<>(); @Override public void customise(OpenAPI openApi) { openApi.getPaths().entrySet().removeIf(entry -> paths.stream().anyMatch(hidePath -> pathMatcher.match(hidePath, entry.getKey())) ); } // paths属性的getter、setter public List<String> getPaths() { return paths; } public void setPaths(List<String> paths) { this.paths = paths; } }
方案2:连带接口本身一起禁用
如果你不仅需要在文档中隐藏接口,还需要配置不满足时接口本身无法调用,可以直接使用@ConditionalOnProperty注解,Spring Boot原生支持该注解标注在方法级别:
@RestController @RequestMapping("/api/internal") public class InternalController { // 配置api.internal.enabled=true时接口才会注册,文档也会自动展示 @ConditionalOnProperty(prefix = "api.internal", name = "enabled", havingValue = "true", matchIfMissing = false) @GetMapping("/config/sync") public void syncConfig() { // 内部逻辑 } }
注意:方案2的优先级高于方案1,接口未注册的情况下不会被springdoc扫描到,不需要额外配置过滤规则。
内容的提问来源于stack exchange,提问作者Vikram Jain
相关产品推荐
相关产品推荐

