Swagger为我们提供了一套通过代码和注解自动生成文档的方法。
1.Swagger简介
Swagger 是一套基于 OpenAPI 规范构建的开源工具,可以帮助我们设计、构建、记录以及使用 Rest API。Swagger 主要包含了以下三个部分:
- Swagger Editor:基于浏览器的编辑器,我们可以使用它编写我们 OpenAPI 规范。
- Swagger UI:它会将我们编写的 OpenAPI 规范呈现为交互式的 API 文档,后文我将使用浏览器来查看并且操作我们的 Rest API。
- Swagger Codegen:它可以通过为 OpenAPI(以前称为 Swagger)规范定义的任何 API 生成服务器存根和客户端 SDK 来简化构建过程。
为什么要使用 Swagger
当下很多公司都采取前后端分离的开发模式,前端和后端的工作由不同的工程师完成。在这种开发模式下,维持一份及时更新且完整的 Rest API 文档将会极大的提高我们的工作效率。传统意义上的文档都是后端开发人员手动编写的,相信大家也都知道这种方式很难保证文档的及时性,这种文档久而久之也就会失去其参考意义,反而还会加大我们的沟通成本。而 Swagger 给我们提供了一个全新的维护 API 文档的方式,下面我们就来了解一下它的优点:
- 代码变,文档变。只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,很好的保证了文档的时效性。
- 跨语言性,支持 40 多种语言。
- Swagger UI 呈现出来的是一份可交互式的 API 文档,我们可以直接在文档页面尝试 API 的调用,省去了准备复杂的调用参数的过程。
- 还可以将文档规范导入相关的工具(例如 SoapUI), 这些工具将会为我们自动地创建自动化测试。
2.SpringBoot Web项目中使用Swagger
1. 编写接口
1.1 创建包:model,controller,test
1.2 在 controller 包下新建 UserController.java 类,在 testcontroller 包下新建 TestController.java 类,在 model 包下新建 User.java 类。
1.3 UserController 提供用户的增、删、改、查四个接口,TestContrller 提供一个测试接口,这里粘上 UserController.java 的代码
public class UserController {
public boolean addUser(@RequestBody User user){
return false;
}
@GetMapping("/find/{id}")
public User findById(@PathVariable("id") int id){
return new User();
}
@PutMapping("/update")
public boolean update(@RequestBody User user){
return true;
}
@DeleteMapping("/delete/{id}")
public boolean delete(@PathVariable int id){
return true;
}
}
2. 集成Swagger2
经过上面的步骤,我们已经拥有了五个接口,分别是:
/user/add:新增用户。
/user/find/{id}:根据 id 查询用户。
/user/update:更新用户。
/user/delete/{id}:根据 id 删除用户。
/test/test:测试接口。
下面我们将通过集成 Swagger2,然后为这 5 个 Rest API 自动生成接口文档。
2.1 添加依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
2.2 Java配置
Springfox 提供了一个 Docket 对象,让我们可以灵活的配置 Swagger 的各项属性。下面我们新建一个 com.steer.config.SwaggerConfig.java 类,并增加如下内容:
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
注解解释:
@Configuration 是告诉 Spring Boot 需要加载这个配置类
@EnableSwagger2 是启用 Swagger2
3.验证
3.1 http://localhost:8080/v2/api-docs
json串启动项目后,我们可以通过在浏览器中访问 http://localhost:8080/v2/api-docs 来验证,您会发现返回的结果是一段 JSON 串,可读性非常差。幸运的是 Swagger2 为我们提供了可视化的交互界面 SwaggerUI
3.2 集成SwaggerUI
- 添加依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
-
http://localhost:8080/swagger-ui.html
SwaggerUI.png
3. 高级配置
1. 在控制器类上增加@Api注解,可以给控制器增加描述和标签信息
@Api(tags = "用户相关接口", description = "提供用户相关的Rest API")
public class UserController {
image.png
2. 通过在接口方法上增加 @ApiOperation 注解来展开对接口的描述,当然这个注解还可以指定很多内容
@ApiOperation("/新增用户接口")
@PostMapping("/add")
public boolean addUser(@RequestBody User user){
return false;
}
image.png
3. 实体描述,我们可以通过 @ApiModel 和 @ApiModelProperty 注解来对我们 API 中所涉及到的对象做描述。
@ApiModel("用户实体")
public class User {
@ApiModelProperty("用户id")
private int id;
private String name;
image.png
4. 文档信息配置,Swagger 还支持设置一些文档的版本号、联系人邮箱、网站、版权、开源协议等等信息,但与上面几条不同的是这些信息不是通过注解配置,而是通过创建一个 ApiInfo 对象,并且使用 Docket.appInfo() 方法来设置,我们在 SwaggerConfig.java 类中新增如下内容即可。
@Bean
public Docket api(){
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo()); // 如果没有文档信息配置,这行就不需要
}
private ApiInfo apiInfo() {
return new ApiInfo(
"Spring Boot项目集成Swagger实例文档",
"文档描述:xxx。",
"version:API V1.0",
"Terms of service",
new Contact("Contact", "https://www.jianshu.com/u/8845b39c7928", "email@gmail.com"),
"Apache", "http://www.apache.org/", Collections.emptyList());
}
image.png
4. 接口过滤
有些时候我们并不是希望所有的 Rest API 都呈现在文档上,这种情况下 Swagger2 提供给我们了两种方式配置,一种是基于 @ApiIgnore 注解,另一种是在 Docket 上增加筛选。
- @ApiIgnore 注解
如果想在文档中屏蔽掉删除用户的接口(user/delete),那么只需要在删除用户的方法上加上 @ApiIgnore 即可
@ApiIgnore
public boolean delete(@PathVariable("id") int id)
- 在 Docket 上增加筛选。Docket 类提供了 apis() 和 paths()两 个方法来帮助我们在不同级别上过滤接口:
- apis():这种方式我们可以通过指定包名的方式,让 Swagger 只去某些包下面扫描。
- paths():这种方式可以通过筛选 API 的 url 来进行过滤。
在集成 Swagger2 中我们这两个方法指定的都是扫描所有,没有指定任何过滤条件。如果我们在我们修改之前定义的 Docket 对象的 apis() 方法和 paths() 方法为下面的内容,那么接口文档将只会展示 /user/add 和 /user/find/{id} 两个接口。
.apis(RequestHandlerSelectors.basePackage("cn.itweknow.sbswagger.controller"))
.paths(Predicates.or(PathSelectors.ant("/user/add"),
PathSelectors.ant("/user/find/*")))
3.相关注解
Controller注解
@Api
注解属性 | 类型 | 描述 |
---|---|---|
tags | String[] | 控制器标签。 |
description | String | 控制器描述(该字段被申明为过期) |
接口相关注解
@ApiOpration
注解属性 | 类型 | 描述 |
---|---|---|
value | String | 接口说明。 |
notes | String | 接口发布说明。 |
tags | Stirng[] | 标签。 |
response | Class<?> | 接口返回类型。 |
httpMethod | String | 接口请求方式。 |
Model相关注解
@ApiModel: 可设置接口相关实体的描述。
@ApiModelProperty: 可设置实体属性的相关描述。
@ApiModelProperty 主要属性:
注解属性 | 类型 | 描述 |
---|---|---|
value | String | 字段说明。 |
name | String | 重写字段名称。 |
dataType | Stirng | 重写字段类型。 |
required | boolean | 是否必填。 |
example | Stirng | 举例说明。 |
hidden | boolean | 是否在文档中隐藏该字段。 |
allowEmptyValue | boolean | 是否允许为空。 |
allowableValues | String | 该字段允许的值,当我们 API 的某个参数为枚举类型时,使用这个属性就可以清楚地告诉 API 使用者该参数所能允许传入的值。 |
网友评论