霸王餐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开发者团队,转载请注明出处!

相关推荐
三十..16 分钟前
MySQL 从入门到高可用架构实战精要
运维·数据库·mysql
云烟成雨TD1 小时前
Spring AI 1.x 系列【51】可观测性技术选型
java·人工智能·spring
unicrom_深圳市由你创科技1 小时前
基于Spring AI框架的RAG应用
人工智能·spring·机器学习
cfm_29141 小时前
Redis五大基本数据结构底层了解
数据结构·数据库·redis
真实的菜2 小时前
Redis 从入门到精通(十二):典型业务场景实战 —— 排行榜、限流器、秒杀系统、Session 共享
数据库·redis·python
linyanRPA2 小时前
影刀RPA店群自动化实战:多店铺活动自动报名与促销管理架构设计
运维·自动化·办公自动化·rpa·python脚本·爬虫自动化·店群自动化
你想考研啊2 小时前
mysql数据库导出导入
数据库·mysql·oracle
小鹿研究点东西2 小时前
直播带货长视频AI自动剪辑开播:一场直播如何反复利用?
ffmpeg·自动化·音视频·语音识别
十年编程老舅3 小时前
Linux DRM:底层逻辑与实践架构
数据库·mysql
七老板的blog3 小时前
当 Spring StateMachine 遇见大模型:构建工业级 AI 写作流水线
java·人工智能·spring