Search code examples
asciidoctorspring-restdocs

Why snippets include error with spring-restdocs-asciidoctor?


i do can generate the index.html when i using spring-restdocs with asciidoctor, but it cannot generate request or response like this.

== /hello: Say "Hello World!"

operation::hello[]

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

.response
include::{snippets}/hello/http-response.adoc[]

here is my config files.

maven dependencies


<dependencies>

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>${junit.jupiter.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web-services</artifactId>
    </dependency>
    <!-- Add Log4j2 Dependency -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    <!-- Needed for Async Logging with Log4j 2 -->
    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>${disruptor.version}</version>
    </dependency>


    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <exclusions>
            <exclusion>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </exclusion>
        </exclusions>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.restdocs</groupId>
        <artifactId>spring-restdocs-mockmvc</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.asciidoctor</groupId>
            <artifactId>asciidoctor-maven-plugin</artifactId>
            <version>${asciidoctor.version}</version>
            <executions>
                <execution>
                    <id>generate-docs</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>process-asciidoc</goal>
                    </goals>
                    <configuration>
                        <backend>html</backend>
                        <doctype>book</doctype>
                        <sourceHighlighter>prettify</sourceHighlighter>
                        <attributes>
                            <toc>left</toc>
                            <icons>font</icons>
                            <sectanchors>true</sectanchors>
                            <idprefix/>
                        </attributes>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.restdocs</groupId>
                    <artifactId>spring-restdocs-asciidoctor</artifactId>
                    <version>${spring-restdocs.version}</version>
                </dependency>
            </dependencies>
        </plugin>
        <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>${maven-resources-plugin.version}</version>
            <executions>
                <execution>
                    <id>copy-resources</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>
                            ${project.build.outputDirectory}/static/docs
                        </outputDirectory>
                        <resources>
                            <resource>
                                <directory>
                                    ${project.build.directory}/generated-docs
                                </directory>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <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>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>${junit.platform.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

this is index.adoc

= blog
:doctype: book
:icons: font
:source-highlighter: highlightjs

== /hello: Say "Hello World!"

operation::hello[]

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

.response
include::{snippets}/hello/http-response.adoc[]

this is my test class

@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith({RestDocumentationExtension.class, SpringExtension.class})
public class HelloControllerTest {
    private MockMvc mockMvc;

    @BeforeEach
    public void setUp(WebApplicationContext webApplicationContext,
                      RestDocumentationContextProvider restDocumentation) {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                .apply(documentationConfiguration(restDocumentation))
                .build();
    }

    @Test
    public void hello() throws Exception {

        mockMvc.perform(get("/hello").param("name", "imckh"))
                .andExpect(status().isOk())
                .andDo(print())
                .andExpect(jsonPath("$.msg", "Hello imckh!").exists())
                .andDo(document("hello",
                        requestParameters(parameterWithName("name").description("The name to retrieve")),
                        responseFields(
                                fieldWithPath("code").description("Code of the response"),
                                fieldWithPath("msg").description("Message of the response"))
                ));
    }
}

When i done testing, it can generate some *.adoc files like 'http-request.adoc, http-response.adoc', generated-snippets then i use maven package, it do can generate a index.html, but it cannot parse below

operation::hello[]

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

.response
include::{snippets}/hello/http-response.adoc[]

generated docs

It get wrong in this step: Including multiple snippets for an operation

Thanks.


Solution

  • You are using version 2.0.0-RC.1 of asciidoctor-maven-plugin with which spring-restdocs-asciidoctor is not compatible. Unfortunately, that incompatibility results in a silent failure to resolve the generated snippets. If you downgrade to 1.6.0 you will at least see a failure caused by the incompatibility.

    You can avoid the problem by using a 1.5.x version of asciidoctor-maven-plugin with which spring-restdocs-asciidoctor in compatible. At the time of writing, 1.5.8 is the latest version. Things work as expected with this version.

    You may also be interested in this Spring REST Docs issue which will hopefully figure out what to do about the breaking changes in AsciidoctorJ once the dust has settled a bit.