Springdoc使用及规范
Springdoc对于Springfox3.0.0的优点
- Springfox对swagger 3的新注解支持的不够,目前已知@Tag和Schema不生效
- Springdoc支持最新版本的Spring和SpringBoot,Springfox不支持
- Springfox更新缓慢,最近一次更新在20年一月,Springdoc有日常更新
集成Springdoc
mvc 项目
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>
webflux项目
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-ui</artifactId>
<version>1.7.0</version>
</dependency>
默认不用添加额外配置就能访问swaggger ui界面
默认访问地址:http://server:port/context-path/swagger-ui.html
关于Swagger 3 注解的使用见Swagger 3 注解使用及规范
(可选)配置
springdoc:
documentation:
enabled: true # 是否开启springdoc openapi端点 默认true
#path: /v3/api-docs ## springdoc openapi端点路径 默认/v3/api-docs
swagger-ui:
enabled: true ## 是否开启 swagger ui 默认true
path: my-swagger.html ## 自定义 swagger访问路径 默认swagger-ui.html
更多配置参见Springdoc-openapi Properties
迁移Springfox到Springdoc
-
移除所有Srpingfox和Swagger 2的依赖,加入Springdoc的依赖集成Springdoc
-
用Swagger 3的注解替换Swagger 2的注解。可以通过IDEA快捷键ctr+shift+r快速替换
-
@Api → @Tag
-
@ApiIgnore → @Parameter(hidden = true) or @Operation(hidden = true) or @Hidden
-
@ApiImplicitParam → @Parameter
-
@ApiImplicitParams → @Parameters
-
@ApiModel → @Schema
-
@ApiModelProperty(hidden = true) → @Schema(accessMode = READ_ONLY)
-
@ApiModelProperty → @Schema
-
@ApiOperation(value = “foo”, notes = “bar”) → @Operation(summary = “foo”, description = “bar”)
-
@ApiParam → @Parameter
-
@ApiResponse(code = 404, message = “foo”) → @ApiResponse(responseCode = “404”, description = “foo”)
-
-
(可选)如果有多个Docket,用GroupedOpenApi替换
Springfox:
@Bean public Docket publicApi() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public")) .paths(PathSelectors.regex("/public.*")) .build() .groupName("springshop-public") .apiInfo(apiInfo()); } @Bean public Docket adminApi() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin")) .paths(PathSelectors.regex("/admin.*")) .apis(RequestHandlerSelectors.withMethodAnnotation(Admin.class)) .build() .groupName("springshop-admin") .apiInfo(apiInfo()); }
Springdoc:
@Bean public GroupedOpenApi publicApi() { return GroupedOpenApi.builder() .group("springshop-public") .pathsToMatch("/public/**") .build(); } @Bean public GroupedOpenApi adminApi() { return GroupedOpenApi.builder() .group("springshop-admin") .pathsToMatch("/admin/**") .addOpenApiMethodFilter(method -> method.isAnnotationPresent(Admin.class)) .build(); }
如果只有一个Docket,可以通过配置来代替
springdoc.packagesToScan=package1, package2 springdoc.pathsToMatch=/v1, /api/balance/**
-
(可选) 自定义文档信息
@Bean public OpenAPI springdocOpenAPI() { return new OpenAPI() .info(new Info().title("SpringShop API") .description("Spring shop sample application") .version("v0.0.1") .license(new License().name("Apache 2.0").url("http://springdoc.org"))) .externalDocs(new ExternalDocumentation() .description("SpringShop Wiki Documentation") .url("https://springshop.wiki.github.org/docs")); }
Swagger 3 使用及规范
统一Swagger配置
所有Swagger有关的配置都应通过开关springdoc.api-docs.enabled
来统一控制,这样可以根据实际需求来开启/关闭Swagger,例如生产环境需要关闭Swagger。
案例
Swagger配置:
@Configuration
@ConditionalOnProperty(value = "springfox.documentation.enabled", havingValue = "true", matchIfMissing = true)
public class SwaggerConfig {
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("springshop-public")
.pathsToMatch("/public/**")
.build();
}
@Bean
public GroupedOpenApi adminApi() {
return GroupedOpenApi.builder()
.group("springshop-admin")
.pathsToMatch("/admin/**")
.addOpenApiMethodFilter(method -> method.isAnnotationPresent(Admin.class))
.build();
}
}
不同环境创建不同配置文件
-
开发环境,需要开启swagger,application-dev.yml内容
springdoc: documentation: enabled: true
-
生产环境,需要关闭swagger防止风险。application-master.yml内容
springdoc: documentation: enabled: false
指定配置生效配置
spring:
profiles:
active: master // 开发环境改为dev
组件的Springdoc依赖设置为可选
当工程是个功能组件时,依赖设置为可选,由组件的使用方去决定要不要引入。
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
<optional>true</optional>
</dependency>
废弃的接口应及时隐藏
@Hidden
@GetMapping("")
public JsonResult<String> queryRoleList() {
return JsonResult.ok();
}
避免分组名称重复
不同模块可以各自配置分组。为了避免分组名称出现重复,分组名称应尽量按照"项目-模块-功能"进行命名
public class OemClientSwaggerConfig {
@Bean("koca-admin-oem-client-openapi")
public GroupedOpenApi api() {
return GroupedOpenApi.builder().group("koca-admin-oem-client")
.packagesToScan("com.szkingdom.koca.admin.oem.client")
.build();
}
}
常用注解
-
@OpenAPIDefinition
用于描述标签、文档信息、安全配置及外部文档,用在类上。一个应用中只会生效一个。
常用参数:
- info:描述文档信息,详情见以下的 @Info
- tags:定义标签列表,详情见以下的 @Tag
- servers:目标服务器连接列表,详情见以下的 @Server
- externalDocs:API 的一些外部文档,详情见以下的 @ExternalDocumentation
示例:
@OpenAPIDefinition(
tags = {
@Tag(name = "用户管理", description = "用户模块操作"),
@Tag(name = "角色管理", description = "角色模块操作")
},
info = @Info(
title = "用户接口 API 文档",
description = "用户数据管理......",
version = "1.0.0",
contact = @Contact(
name = "lanweihong",
email = "986310747@qq.com",
url = "https://www.lanweihong.com"
),
license = @License(
name = "Apache 2.0",
url = "http://www.apache.org/licenses/LICENSE-2.0.html"
)
),
servers = {
@Server(description = "生产环境服务器", url = "https://xxxx.com/api/v1"),
@Server(description = "测试环境服务器", url = "https://test.xxxx.com/api/v1")
},
security = @SecurityRequirement(name = "Oauth2"),
externalDocs = @ExternalDocumentation(
description = "项目编译部署说明",
url = "http://localhost/deploy/README.md"
)
)
-
@Info
用于说明文档信息,用在 @OpenAPIDefinition 中。
常用参数:
- title:应用标题
- description:应用描述
- contact:联系信息,详情看 @Contact
- license:许可信息,详情看 @License
- version:版本
示例:
@OpenAPIDefinition(
info = @Info(
title = "用户接口 API 文档",
description = "用户数据管理......",
version = "1.0.0",
contact = @Contact(name = "lanweihong", email = "986310747@qq.com", url = "https://www.lanweihong.com"),
license = @License(name = "Apache 2.0", url = "http://www.apache.org/licenses/LICENSE-2.0.html")
)
)
-
@Tag
对一个 operation 进行说明或定义的标签,用在类或方法上,也可以用在 @OpenAPIDefinition 中定义标签。
常用参数:
- name:名称
- description:描述
示例:
用在类上:
@Tag(name = "用户管理")
@RestController
public class UserController {
// ···
}
用在 @OpenAPIDefinition 中定义标签:
@OpenAPIDefinition(
tags = {
@Tag(name = "用户管理", description = "用户模块操作"),
@Tag(name = "角色管理", description = "角色模块操作")
}
)
-
@Contact
用于描述联系人信息,用在 @Info 中。
常用参数:
- name:唯一名称(个人/组织)
- url:指向联系人信息的 URL
- email:邮箱
示例:
@OpenAPIDefinition(
info = @Info(
contact = @Contact(
name = "Li.chen",
email = "mail",
url = "www"
)
)
)
-
@License
用于描述许可证信息,用在 @Info 中。
常用参数:
- name:许可证名称
- url:指向许可证的 URL
示例:
@OpenAPIDefinition(
servers = {
@Server(description = "生产环境服务器", url = "https://xxxx.com/api/v1"),
@Server(description = "测试环境服务器", url = "https://test.xxxx.com/api/v1")
}
)
- Server
用于配置目标主机,用在 @OpenAPIDefinition 中。
常用参数:
- url:主机地址
- description:主机描述
示例:
@OpenAPIDefinition(
servers = {
@Server(description = "生产环境服务器", url = "https://xxxx.com/api/v1"),
@Server(description = "测试环境服务器", url = "https://test.xxxx.com/api/v1")
}
)
-
@Operation
用于说明方法用途,用在方法上。
参数:
- summary:方法概要,方法的一个简单介绍,建议 120 个字符内
- description:方法描述,一般是很长的内容
- hidden:是否隐藏
示例:
@Operation(summary = "查询用户列表", description = "返回所有用户数据")
@GetMapping("/users")
public String getUseList() {
return "";
}
-
@Parameter
用于说明方法参数,用在方法参数上。
参数:
- name:指定的参数名
- in:参数位置,可选 query、header、path 或 cookie,默认为空,表示忽略
- description:参数描述
- required:是否必填,默认为 false
示例:
@Operation(summary = "删除用户")
@DeleteMapping("/users/{username}")
public JsonResult<UserVO> deleteUserByName(
@Parameter(name = "username", in = ParameterIn.PATH, description = "用户名", required = true)
@PathVariable("username") String userName
) {
// TODO
return JsonResult.ok();
}
-
@ApiResponse
用于说明一个响应信息,用在 @ApiResponses 中。
参数:
- responseCode:HTTP 响应码
- description:描述
示例:
@Operation(summary = "通过用户名查询用户", description = "根据用户名查询用户详细信息")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "请求成功"),
@ApiResponse(responseCode = "404", description = "用户不存在", content = @Content)
})
@GetMapping("/{username}")
public JsonResult<UserVO> getUserByName(@Parameter(description = "用户名", required = true) @PathVariable("username") String userName) {
// TODO
return JsonResult.ok();
}
-
@ApiResponses
用于说明一组响应信息,比如一个请求可能返回多种响应情况,比如成功信息(200),也有可能抛参数异常(400),用在方法上。
参数:
- value:@ApiResponse 数组
示例参考以上的 @ApiResponse。
11. @Schema
用于描述数据对象信息或数据对象属性,比如各种 POJO 类及属性,用在类或类属性上。
参数:
- name:属性名称
- description:属性描述
- required:是否必须
- minLength:字符最小长度
- maxLength:字符最大长度
示例:
@Schema(description = "用户实体")
public class UserVO {
@Schema(description = "用户名")
private String userName;
@Schema(description = "邮箱")
private String email;
// Getter And Setter ...
}
-
@Hidden
用于隐藏资源、类或属性,用在类、方法或属性上。
示例:
@RestController
@RequestMapping("/api/roles")
// 隐藏整个 RoleController
@Hidden
public class RoleController {
@GetMapping("")
public JsonResult<String> queryRoleList() {
return JsonResult.ok();
}
}