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>
    
  2. application.yml

    server:
    port: 9010
    spring:
    application:
    name: learn-restdoc
    
  3. RestDocApplication.java

    @SpringBootApplication
    public class RestDocApplication {
    public static void main(String[] args) {
        SpringApplication.run(RestDocApplication.class, args);
    }
    }
    
  4. HomeController.java

    @RestController
    public class HomeController {
    @GetMapping("/")
    public Map<String, Object> greeting() {
        return Collections.singletonMap("message", "Hello World");
    }
    }
    
  5. SpringbootRestdocsApplicationTests.java

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringbootRestdocsApplicationTests {
    
    @Test
    public void contextLoads() {
    }
    
    }
    
  6. 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"));
    }
    }
    
  7. 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[]
    
  8. 云顶WebLayerTest会生成target/snippets/home几个.adoc文件,如http-request.adoc,response-body.adoc等。

  9. 运行打包命令,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文档。