Spring Boot教程第10篇:restdoc

Spring REST Docs的目标是帮助您为您的RESTful服务生成准确可读的文档。

编写高质量的文档很困难。减轻这种困难的一种方法是使用非常适合工作的工具。为此,Spring REST Docs 默认使用Asciidoctor。Asciidoctor处理纯文本并生成HTML,进行样式化和布局以满足您的需求。如果您愿意,还可以将Spring REST Docs配置为使用Markdown。

Spring REST Docs利用Spring MVC的测试框架 Spring WebFlux WebTestClientREST Assured 3编写的测试生成的代码片段。这种测试驱动的方法有助于保证服务文档的准确性。如果代码片段不正确,则生成它的测试将失败。

  1. pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>learnboot</artifactId>
        <groupId>tk.amrom</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>learnrestdoc</artifactId>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.restdocs/spring-restdocs-mockmvc -->
        <dependency>
            <groupId>org.springframework.restdocs</groupId>
            <artifactId>spring-restdocs-mockmvc</artifactId>
            <version>2.0.4.RELEASE</version>
            <scope>test</scope>
        </dependency>

    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.asciidoctor</groupId>
                <artifactId>asciidoctor-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>generate-docs</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <sourceDocumentName>index.adoc</sourceDocumentName>
                            <backend>html</backend>
                            <attributes>
                                <snippets>${project.build.directory}/snippets</snippets>
                            </attributes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
  1. application.yml
server:
  port: 9010
spring:
  application:
    name: learn-restdoc
  1. RestDocApplication.java
@SpringBootApplication
public class RestDocApplication {
    public static void main(String[] args) {
        SpringApplication.run(RestDocApplication.class, args);
    }
}
  1. HomeController.java
@RestController
public class HomeController {
    @GetMapping("/")
    public Map<String, Object> greeting() {
        return Collections.singletonMap("message", "Hello World");
    }
}
  1. SpringbootRestdocsApplicationTests.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRestdocsApplicationTests {

    @Test
    public void contextLoads() {
    }

}
  1. WebLayerTest.java
import learnrestdoc.controller.HomeController;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.hamcrest.Matchers.containsString;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@WebMvcTest(HomeController.class)
@AutoConfigureRestDocs(outputDir = "target/snippets")
public class WebLayerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void shouldReturnDefaultMessage() throws Exception {
        this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk())
                .andExpect(content().string(containsString("Hello World")))
                .andDo(document("home"));
    }
}
  1. src/main/asciidoc/index.adoc
This is an example output for a service running at http://localhost:8080:

.request

include::{snippets}/home/http-request.adoc[]

.response

include::{snippets}/home/http-response.adoc[]
  1. 云顶WebLayerTest会生成target/snippets/home几个.adoc文件,如http-request.adoc,response-body.adoc等。
  2. 运行打包命令,mvn package, 在打包输出目录target/generated-docs有index.html文件,打开即可看到生成的api文档。
This is an example output for a service running at http://localhost:8080:

request
GET / HTTP/1.1
Host: localhost:8080
response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 25

{"message":"Hello World"}

总结

spring rest doc通过运行Spring Test把每个测试结果生成adoc文件,再通过打包输出,实现了静态的api文档。