首页 > 编程笔记 > Java笔记 阅读:10

Spring Boot用Swagger生成Web API文档详解

高质量的 API 文档在系统开发的过程中非常重要。Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务,是非常流行的 API 表达工具。

我们知道,RESTful API 可能要面对多个开发人员或多个开发团队,涉及不同平台,包括 iOS、Android 或 Web 前端等。为了降低与其他团队频繁沟通的成本,一般我们会创建一份统一的 API 说明文档来记录所有接口的使用说明。

然而,普通的 API 文档存在以下问题:
1) 由于接口众多,并且细节复杂(需要考虑不同的 HTTP 请求类型、HTTP 头部信息、HTTP 请求内容等),创建这样一份高质量的文档是一件非常烦琐的工作。

2) 随着需求的不断变化,接口文档必须同步修改,就很容易出现文档和业务不一致的情况。

为了解决这些问题,Swagger 应运而生,它能够自动生成完善的 RESTful API 文档,并根据后台代码的修改同步更新。这样既可以减少维护接口文档的工作量,又能将说明内容集成到实现代码中,让维护文档和修改代码合为一体,实现代码逻辑与说明文档的同步更新。另外,Swagger 也提供了完整的测试页面来调试 API,让 API 测试变得轻松、简单。

用Swagger生成Web API文档

Spring Boot 项目中集成 Swagger 同样非常简单,只需在项目中引入 springfox-swagger2 和 springfox-swagger-ui 依赖即可。

下面就以之前的用户管理模块接口为例来感受 Swagger 的魅力。

1) 配置Swagger的依赖

<!-- swagger2 依赖配置-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.8.0</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.8.0</version>
</dependency>
在上面的示例中,在项目 pom.xml 配置文件中引入了 springfox-swagger2 和 springfox-swagger-ui 两个依赖包。其中 swagger2 是主要的文档生成组件,swagger-ui 为页面显示组件。

2) 创建Swagger2配置类

@Configuration
@EnableSwagger2
public class Swagger2Config implements WebMvcConfigurer {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.weiz.example01.controller"))
                .paths(PathSelectors.any())
                .build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Spring Boot中使用Swagger2构建RESTful APIs")
                .description("Spring Boot相关文章请关注:https://www.cnblogs.com/zhangweizhong")
                .termsOfServiceUrl("https://www.cnblogs.com/zhangweizhong")
                .contact("架构师精进")
                .version("1.0")
                .build();
    }
    /**
     *  swagger增加url映射
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}
在上面的示例中,我们在 SwaggerConfig 的类上添加了 @Configuration 和 @EnableSwagger2 两个注解。
apiInfo 主要配置 Swagger2 文档网站的信息,比如网站的标题、网站的描述、使用的协议等。

需要注意的是:

3) 添加文档说明内容

上面的配置完成之后,接下来需要在 API 上增加内容说明。我们直接在之前的用户管理模块的 UserController 中增加相应的接口内容说明,代码如下:
@Api(tags = {"用户接口"})
@RestController
public class UserController {

    @ApiOperation(value="创建用户", notes="根据User对象创建用户")
    @PostMapping(value = "user")
    public JSONResult save(@RequestBody User user){
        System.out.println("用户创建成功:"+user.getName());
        return JSONResult.ok(201,"用户创建成功");
    }

    @ApiOperation(value="更新用户详细信息", notes="根据id来指定更新对象,并根据传过来的user信息来更新用户详细信息")
    @PutMapping(value = "user")
    public JSONResult update(@RequestBody User user) {
        System.out.println("用户修改成功:"+user.getName());
        return JSONResult.ok(203,"用户修改成功");
    }

    @ApiOperation(value="删除用户", notes="根据url的id来指定删除对象")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "Long", paramType = "query")
    @DeleteMapping("user/{userId}")
    public JSONResult delete(@PathVariable String userId) {
        System.out.println("用户删除成功:"+userId);
        return JSONResult.ok(204,"用户删除成功");
    }

    @ApiOperation(value="查询用户",notes = "通过用户ID获取用户信息")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "Long", paramType = "query")
    @GetMapping("user/{userId}")
    public JSONResult queryUserById(@PathVariable String userId) {
        User user =new User();
        user.setUserId(userId);
        user.setName("weiz");
        user.setAge(20);
        System.out.println("获取用户成功:"+userId);
        return JSONResult.ok(200,"获取用户成功",user);
    }
}
在上面的示例中,主要为 UserController 中的接口增加了接口信息描述,包括接口的用途、请求参数说明等:

4) 查看生成的API文档

完成上面的配置和代码修改之后,Swagger 2 就集成到 Spring Boot 项目中了。接下来启动项目,在浏览器中访问 http://localhost:8080/swagger-ui.html,Swagger 会自动构建接口说明文档,如下图所示:


图 1 Swagger-UI启动页面

Swagger 自动将用户管理模块的全部接口信息展现出来,包括接口功能说明、调用方式、请求参数、返回数据结构等信息。

在 Swagger 页面上,我们发现每个接口描述右侧都有一个按钮 try it out,单击 try it out 按钮即可调用该接口进行测试。如下图所示:


图 2 Swagger接口验证测试

在获取人员信息的接口上单击 try it out 按钮,输入 userId 的请求参数“2001”,单击 Execute 按钮就会将请求发送到后台,从而进行接口验证测试。

为Swagger添加token参数

很多时候,客户端在调用 API 时需要在 HTTP 的请求头携带通用参数,比如权限验证的 token 参数等。但是 Swagger 是怎么描述此类参数的呢?接下来通过示例演示如何为 Swagger 添加固定的请求参数。

其实非常简单,修改 Swagger2Config 配置类,利用 ParameterBuilder 构成请求参数。具体示例代码如下:
@@Configuration
@EnableSwagger2
public class Swagger2Config implements WebMvcConfigurer {
    @Bean
    public Docket createRestApi() {
                // 添加请求参数,这里把token作为请求头参数传入后端
                ParameterBuilder parameterBuilder = new ParameterBuilder();
                List<Parameter> parameters = new ArrayList<Parameter>();
                parameterBuilder.name("token").description("token令牌")
                                .modelRef(new ModelRef("string")).parameterType("header").required(false).build();
                parameters.add(parameterBuilder.build());

                return new Docket(DocumentationType.SWAGGER_2)
                                .apiInfo(apiInfo())
                                .select()

                                .apis(RequestHandlerSelectors.basePackage("com.weiz.example01.controller"))
                                .paths(PathSelectors.any())
                                .build()
                                .globalOperationParameters(parameters);
    }

   …
}
在上面的示例中,通过 ParameterBuilder 类把 token 作为全局统一的参数添加到 HTTP 的请求头中。系统所有的 API 都会统一加上此参数。

完成之后重新启动应用,再次查看接口,如下图所示:


图 3 添加token参数

我们可以看到接口参数中已经支持发送 token 请求参数。

人员管理模块中的所有 API 都统一加上了 token 参数,调用时 Swagger 会将 token 参数自动加入 HTTP 的请求头。

Swagger常用注解

Swagger 提供了一系列注解来描述接口信息,包括接口说明、请求方法、请求参数、返回信息等,常用注解如下表所示。

表:Swagger常用注解说明

注解 属性 值类型 说明 示例
@Api value 字符串 可用在 class 头上,class 描述 @Api(value = "xxx", description = "xxx")
  description 字符串    
@ApiOperation value 字符串 可用在方法头上,参数的描述容器 @ApiOperation(value = "xxx", notes = "xxx")
  notes 字符串    
@ApiImplicitParams   @ApiImplicitParam 数组 可用在方法头上,参数的描述容器 @ApiImplicitParams({@ApiImplicitParam1,@ApiImplicitParam2,...})
@ApiImplicitParam name 字符串,与参数命名对应 可用在 @ApiImplicitParams 中 用例参见项目中的设置
  value 字符串 参数中文描述  
  required 布尔值 true / false  
  dataType 字符串 参数类型  
  paramType 字符串 参数请求方式:query / path  
  defaultValue 字符串 在 API 测试中的默认值  
@ApiResponses {} @ApiResponse 数组 可用在方法头上,参数的描述容器 @ApiResponses({@ApiResponse1,@ApiResponse2,...})
@ApiResponse code 整数 可用在 @ApiResponses 中 @ApiResponse(code = 200, message = "Successful")
  message 字符串 错误描述  
@ApiIgnore     忽略这个 API  
@ApiError     发生错误的返回信息  

在实际项目中,Swagger 除了提供 @ApiImplicitParams 注解描述简单的参数之外,还提供了用于对象参数的 @ApiModel 和 @ApiModelProperty 两个注解,用于封装的对象作为传入参数或返回数据:
以上是在项目中常用的一些注解,利用这些注解就可以构建出清晰的 API 文档。

相关文章