霸王餐API文档自动化:Spring REST Docs与Asciidoctor多模块聚合

霸王餐API文档自动化:Spring REST Docs与Asciidoctor多模块聚合

项目结构与目标

"吃喝不愁"App后端采用多模块Maven工程,包含 order-serviceuser-servicecoupon-service 等。每个模块独立提供REST API,需统一生成一份完整、可部署的HTML API文档。目标:

  • 测试即文档,杜绝接口与文档不一致;
  • 支持多模块测试结果聚合;
  • 输出结构化、带示例请求/响应的静态文档。

技术栈:Spring REST Docs + Asciidoctor + Maven插件聚合。

子模块配置(以coupon-service为例)

juwatech.cn.coupon 模块中引入依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.restdocs</groupId>
    <artifactId>spring-restdocs-mockmvc</artifactId>
    <scope>test</scope>
</dependency>

编写测试用例:

java 复制代码
package juwatech.cn.coupon;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureRestDocs(outputDir = "target/generated-snippets")
public class CouponApiDocumentation {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void getCouponDetail() throws Exception {
        this.mockMvc.perform(get("/api/coupons/{couponId}", "cp_12345")
                .header("X-User-ID", "u_789"))
            .andExpect(status().isOk())
            .andDo(MockMvcRestDocumentation.document("coupon-get-detail",
                pathParameters(
                    parameterWithName("couponId").description("优惠券ID")
                ),
                responseFields(
                    fieldWithPath("code").type(JsonFieldType.STRING).description("状态码"),
                    fieldWithPath("data.id").type(JsonFieldType.STRING).description("优惠券ID"),
                    fieldWithPath("data.title").type(JsonFieldType.STRING).description("标题"),
                    fieldWithPath("data.validUntil").type(JsonFieldType.STRING).description("有效期至 (ISO8601)")
                )
            ));
    }
}

执行 mvn test 后,生成 target/generated-snippets/coupon-get-detail/ 目录,含 http-request.adocpath-parameters.adoc 等片段。

子模块Asciidoc源文件

src/main/asciidoc/coupon-api.adoc 中引用片段:

asciidoc 复制代码
[[coupon-api]]
== 优惠券接口

=== 获取优惠券详情

include::{snippets}/coupon-get-detail/http-request.adoc[]
include::{snippets}/coupon-get-detail/path-parameters.adoc[]
include::{snippets}/coupon-get-detail/response-fields.adoc[]
include::{snippets}/coupon-get-detail/http-response.adoc[]

聚合模块:docs-aggregator

新建独立Maven模块 docs-aggregator,负责收集所有子模块的snippets和adoc源文件。

pom.xml 配置:

xml 复制代码
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <executions>
        <execution>
          <id>unpack-snippets</id>
          <phase>generate-resources</phase>
          <goals><goal>unpack</goal></goals>
          <configuration>
            <artifactItems>
              <artifactItem>
                <groupId>juwatech.cn</groupId>
                <artifactId>coupon-service</artifactId>
                <version>${project.version}</version>
                <type>jar</type>
                <includes>**/generated-snippets/**</includes>
                <outputDirectory>${project.build.directory}/snippets</outputDirectory>
              </artifactItem>
              <artifactItem>
                <groupId>juwatech.cn</groupId>
                <artifactId>order-service</artifactId>
                <version>${project.version}</version>
                <type>jar</type>
                <includes>**/generated-snippets/**</includes>
                <outputDirectory>${project.build.directory}/snippets</outputDirectory>
              </artifactItem>
            </artifactItems>
          </configuration>
        </execution>
        <execution>
          <id>unpack-asciidoc</id>
          <phase>generate-resources</phase>
          <goals><goal>unpack</goal></goals>
          <configuration>
            <artifactItems>
              <artifactItem>
                <groupId>juwatech.cn</groupId>
                <artifactId>coupon-service</artifactId>
                <version>${project.version}</version>
                <type>jar</type>
                <includes>**/*.adoc</includes>
                <outputDirectory>${project.build.directory}/asciidoc</outputDirectory>
              </artifactItem>
              <!-- order-service 同理 -->
            </artifactItems>
          </configuration>
        </execution>
      </executions>
    </plugin>

    <plugin>
      <groupId>org.asciidoctor</groupId>
      <artifactId>asciidoctor-maven-plugin</artifactId>
      <version>2.2.4</version>
      <executions>
        <execution>
          <id>generate-docs</id>
          <phase>prepare-package</phase>
          <goals><goal>process-asciidoc</goal></goals>
          <configuration>
            <sourceDocumentName>index.adoc</sourceDocumentName>
            <backend>html5</backend>
            <attributes>
              <snippets>${project.build.directory}/snippets</snippets>
            </attributes>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

主文档 index.adoc

docs-aggregator/src/main/asciidoc/index.adoc 中聚合各模块:

asciidoc 复制代码
= 吃喝不愁霸王餐API文档
:doctype: book
:icons: font
:source-highlighter: highlightjs
:toc: left

include::{projectdir}/target/asciidoc/coupon-api.adoc[]
include::{projectdir}/target/asciidoc/order-api.adoc[]

构建与输出

执行:

bash 复制代码
mvn clean install -pl coupon-service,order-service
mvn package -pl docs-aggregator

最终生成 docs-aggregator/target/generated-docs/index.html,包含所有服务的完整API文档,支持直接部署至Nginx或对象存储。

注意事项

  • 子模块需将 src/main/asciidoc 打包进JAR:

    xml 复制代码
    <resources>
      <resource>
        <directory>src/main/asciidoc</directory>
      </resource>
    </resources>
  • 测试类必须使用 @AutoConfigureRestDocs 并指定 outputDir

  • 字段描述需精确,避免模糊用语如"相关信息"。

本文著作权归吃喝不愁app开发者团队,转载请注明出处!

相关推荐
JavaGuide16 小时前
Claude Opus 4.6 真的用不起了!我换成了国产 M2.5,实测真香!!
java·spring·ai·claude code
爱可生开源社区18 小时前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
玹外之音18 小时前
Spring AI MCP 实战:将你的服务升级为 AI 可调用的智能工具
spring·ai编程
来一斤小鲜肉19 小时前
Spring AI入门:第一个AI应用跑起来
spring·ai编程
NE_STOP21 小时前
springMVC-常见视图组件与RESTFul编程风格
spring
随逸1771 天前
《从零搭建NestJS项目》
数据库·typescript
加号32 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏2 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐2 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再2 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip