一、API接口文档演进历史

API接口文档是伴随着前后端分离的开发模式而出现的,并且经历了几个重要演进。

1_resize

1.1 史前时期 - 不分家

在上古时期,程序员不分为前端和后端,统称Javaweb开发人员。没有存粹的前端开发人员。
技术框架以Struts和SpringMVC为。主页面渲染在后端处理。前端主要使用jQuery。
程序员仅在对外部提供跨系统调用的接口时会编写文档,一般以word或excel文档形式提供。

1.2 模板引擎时期 - 切图交付

在这个时期,专业的前端人员开始出现,但是工作仅仅是讲UI设计图转化为HTML静态页面,并交付给后端开发人员。
页面渲染放到了前端技术栈,这个时期形成了各种模板引擎。

1.3 手工编写

前后端的开发人员在开发前约定接口定义,形成文档。文档由后端研发手工维护。以wiki、cf等形式发布。
前端技术栈形成了React、Vue等重量级框架。

1.4 注解生成

随着时代的发展,根据Java代码中的注解来生成文档,又分为离线文档和在线文档两种。
我们后续主要介绍根据注解生成在线文档这种形式。

二、Knife4j介绍

knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案。无缝兼容Swagger规范、和Knife4j增强注解(解决Swagger不支持的部分功能),界面比Swagger易于使用。可以与标准Swagger共存。

2.1 总体概况

2_resize

2.2 核心功能

2.2.1 接口文档浏览

接口会根据分组进行显示,点击某一个接口名称后,右侧主界面会新增一个Tab页面显示这个接口的详细信息,其中包括:

  • 请求地址
  • 请求类型
  • 请求参数与数据类型
  • 响应参数与数据类型
  • 响应示例(json格式)

3

2.2.2 Swagger Models

Swagger Models界面可以看到工程中全部的实体类,方便统一查看与检索。每个实体类中会显示名称和类型。
4

2.2.3 在线调试

每个接口都可以直接在界面中进行调试,通过自定义请求参数进行接口测试,并取得返回值帮助前端开发。而且支持权限验证,通过全局参数的设置,可以模拟Token或者cookie携带写入header中。
调试界面如图所示:
5

2.2.4 OpenAPI生成

为了便于与其他系统进行集成,比如YAPI或Postman等调试工具导入接口,Knife4j提供了标准OpenAPI格式的接口定义。
访问你的工程路径+/v2/api-docs或/v3/api-docs(根据你引用的Knife4j版本决定)即可打开OpenAPI接口定义。
如下图所示:
12

2.3 集成到Java工程

2.3.1 引入jar包

Knife4j支持springboot,可直接在maven中配置。

	<!-- Knife4j -->
	<dependency>
		<groupId>com.github.xiaoymin</groupId>
		<artifactId>knife4j-spring-boot-starter</artifactId>
		<version>3.0.3</version>
	</dependency>

2.3.2 创建Swagger配置依赖

通过Spring注解的方式初始化Knife4j配置。

@Configuration
@EnableSwagger2
@EnableKnife4j
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2) // DocumentationType.SWAGGER_2 固定的,代表swagger2
                .apiInfo(apiInfo()) // 用于生成API信息
                .select() // select()函数返回一个ApiSelectorBuilder实例,用来控制接口被swagger做成文档
                .apis(RequestHandlerSelectors.basePackage("com.viewhigh.pacific.index.controller")) // 用于指定扫描哪个包下的接口
                .paths(PathSelectors.any())// 选择所有的API,如果你想只为部分API生成文档,可以配置这里
                .build();
    }

    /**
     * 用于定义API主界面的信息,比如可以声明所有的API的总标题、描述、版本
     * @return ApiInfo 页面显示信息
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("XXX平台 - 系统服务API") // 可以用来自定义API的主标题
                .description("系统服务") // 可以用来描述整体的API
                .termsOfServiceUrl("") // 用于定义服务的域名
                .version("1.0") // 可以用来定义版本。
                .build(); //
    }
}

2.3.3 微服务聚合(可选)

Knife4j不仅可以按照服务单独显示文档,也支持将多个服务的文档聚合显示,如下图所示:
6

2.4 注解编写要点

本章节介绍Knife4j在编写时的主要内容。

2.4.1 类前注解

我们在Controller层的类前要添加@Api注解,每个Controller前都必须添加。
Knife4j会根据改注解中的tags进行接口分组,相同名称的接口会分到同一组中进行展示。
如下图所示:
7

2.4.2 方法前注解

Knife4j会识别出Controller的每个方法为一个接口,所以为保证API接口文档的可读性,每个方法前均需要添加@ApiOperation注解。
还有一个注意的地方就是必须使用@PostMapping或者@GetMapping等注解指定数据类型,不能只使用@RequestMapping注解不指定类型,如果不指定类型,同一个接口会在Knife4j中被识别为多个接口,影响可读性。
如下图所示:
8

2.4.3 实体类注解

实体类的类前要添加@ApiModel注解。
每个字段前要添@ApiModelProperty注解,其中常用的参数有三个,value是字段名称、required是否必填项、hidden是否在API接口文档中显示。
为了更好的区分入参和出参,我们在入参时统一使用Dto,出参使用Vo。
除非字段一模一样,否则不使用默认生成的Entity作为入出参。这样可以保证生成的API文档没有冗余的字段,可读性高。
如下图所示:
9

2.4.4 其他注意事项

  • 在生产环境要关闭Knife4j,避免安全风险。有两种方法:动态spring profile、application.yml配置。
    10
  • 如果使用代码生成器,要删除Controller中没被使用的增删改查方法。
  • Controller中的方法必须指定数据类型。
  • 使用 ApiModel 注解时,中文名称全局唯一。名称必须相同时,可用value定义类名,description定义中文名称。
    11

三、总结

总体来说,Knife4j是易于使用、界面美观、集成简单的API文档解决方案。
推荐开发方式是前后端分离的团队使用。

四、相关资源

官网:https://doc.xiaominfo.com/knife4j/
文档:https://doc.xiaominfo.com/knife4j/documentation/
源码地址:https://gitee.com/xiaoym/knife4j