欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

API文档自动生成工具Swagger VS Spring REST Doc

程序员文章站 2022-07-02 21:00:33
...

背景

随着项目工程的数量越来越多,项目的接口也越来越多,编写接口的API文档的工作量逐渐增大,同时当接口出现变动的时候,文档往往有时无法实时同步,因此考虑采用自动生成API文档的方式管理项目。

工具选择

目前市面上比较主流的API文档生成工具是Swagger与Spring rest doc,下面对这个工具的使用方式进行一下比较。

Swagger

Swagger是一种Rest API的 简单但强大的表示方式,标准的,语言无关,这种 表示方式不但人可读,而且机器可读。 可以作为Rest API的交互式文档,也可以作为Rest API的形式化的接口描述,生成客户端和服务端的代码。

Swagger对Java有很好的支持,可以集成于Spring boot中。

通过Swagger的注解,在controller的方法上进行标注,项目启动后,即可通过静态页面访问的方式,获取到API接口的文档信息。

目录结构

API文档自动生成工具Swagger VS Spring REST Doc

示例中使用的Swagger2,我们需要在项目中引入swagger-ui的静态文件包,用于静态页显示API文档,在controller层,需要生产文档说明的方法上加入@ApiOperation的注解,

说明该方法的用途,在方法入参前,加入@ApiParam注解,说明该参数的名称,通过这些Swagger的注解,在项目启动时,Swagger会扫描指定的包中的注解,最终生产一个大的JSON串,

项目启动后访问:http://localhost:8080/v2/api-docs即可看到,引入swagger-ui后,需要修改index.html中的URL访问地址,获取到这个JSON串,进行静态图形化页面的展示。

API文档自动生成工具Swagger VS Spring REST Doc

生成效果

项目启动后,访问:http://localhost:8080/swagger-ui.html,即可出现API文档的界面。

API文档自动生成工具Swagger VS Spring REST Doc

Spring Rest doc

Spring rest doc是基于swagger的一个工具,对Swagger进行了扩展,基本注解来自于Swagger,只不过在生成文档的方式上有所不同,Spring rest doc是通过maven构建的方式来生成文档静态页面,不需要手动引入swagger的静态文件库,

这一点上比swagger会方便一些,但是需要在maven中进行配置。

目录结构

Spring rest doc需要在maven打包时引入一些配置,

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <includes>
                    <include>**/*Documentation.java</include>
                </includes>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.asciidoctor</groupId>
            <artifactId>asciidoctor-maven-plugin</artifactId>
            <version>1.5.3</version>

            <!-- Configure generic document generation settings -->
            <configuration>
                <sourceDirectory>${project.basedir}/docs/asciidoc</sourceDirectory>
                <sourceDocumentName>index.adoc</sourceDocumentName>
                <attributes>
                    <doctype>book</doctype>
                    <toc>left</toc>
                    <toclevels>3</toclevels>
                    <numbered></numbered>
                    <hardbreaks></hardbreaks>
                    <sectlinks></sectlinks>
                    <sectanchors></sectanchors>
                    <generated>${project.build.directory}/asciidoc</generated>
                </attributes>
            </configuration>
            <!-- Since each execution can only handle one backend, run
                 separate executions for each desired output type -->
            <executions>
                <execution>
                    <id>output-html</id>
                    <phase>test</phase>
                    <goals>
                        <goal>process-asciidoc</goal>
                    </goals>
                    <configuration>
                        <backend>html5</backend>
                        <!--<outputDirectory>${project.basedir}/docs/asciidoc/html</outputDirectory>-->
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

同时在单元测试中,增加使用mock,对controller层的方法进行调用:

/**
 * Created by xuangy on 2018/8/3.
 */
@AutoConfigureMockMvc
@AutoConfigureRestDocs(outputDir = "target/generated-snippets")
@RunWith(SpringRunner.class)
@SpringBootTest
public class Documentation {

    private String snippetDir = "target/generated-snippets";
    private String outputDir = "target/asciidoc";
    //private String indexDoc = "docs/asciidoc/index.adoc";

    @Autowired
    private MockMvc mockMvc;

    @After
    public void Test() throws Exception{
        // 得到swagger.json,写入outputDir目录中
        mockMvc.perform(get("/v2/api-docs").accept(MediaType.APPLICATION_JSON))
                .andDo(SwaggerResultHandler.outputDirectory(outputDir).build())
                .andExpect(status().isOk())
                .andReturn();

        // 读取上一步生成的swagger.json转成asciiDoc,写入到outputDir
        // 这个outputDir必须和插件里面<generated></generated>标签配置一致
        Swagger2MarkupConverter.from(outputDir + "/swagger.json")
                .withPathsGroupedBy(GroupBy.TAGS)// 按tag排序
                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)// 格式
                .withExamples(snippetDir)
                .build()
                .intoFolder(outputDir);// 输出
    }

    @Test
    public void TestApi() throws Exception{
        mockMvc.perform(get("/student").param("name", "szl")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andDo(MockMvcRestDocumentation.document("getStudent", preprocessResponse(prettyPrint())));

        Student student = new Student();
        student.setName("宣");
        student.setAge(2);
        student.setAddress("北京");
        student.setCls("ss");
        student.setSex("男");

        mockMvc.perform(post("/student").contentType(MediaType.APPLICATION_JSON)
                .content(JSON.toJSONString(student))
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().is2xxSuccessful())
                .andDo(MockMvcRestDocumentation.document("addStudent", preprocessResponse(prettyPrint())));
    }
}

生成效果

执行maven install,会在我们在pom文件中指定的位置生成一个index.html文件,访问该文件:

API文档自动生成工具Swagger VS Spring REST Doc

总结

上面展示了两种工具生成API文档的效果,现在对比一下两个文档。

两个工具都是采用扫描注解的方式,来生成静态页面文档,其中Spring rest doc我可以理解为Swagger的Spring增强版,本质上也是基于Swagger的,两种方式都会对代码有一定的侵入,

需要在controller层(还有entity实体层,如果你希望生成实体的注释的话)加入注解,Spring rest doc的侵入更大一些,需要maven的打包方式加入支持,相对来讲,swagger会更轻量级一些,

不需要对maven的打包方式进行修改,也不需要使用mock生成静态页,但是需要在项目中引入swagger-ui的静态文件包。

Spring Rest Doc会更加强大一些,生成的文档界面会更加的漂亮,但是也更加的笨重。