☰
springdoc-openapi-demos:Spring Boot 接口文档生成实践
2026/10/26 5:03:17 网站建设 项目流程

简介:《springdoc-openapi-demos》是一份围绕 Spring Boot 与 OpenAPI 3 集成实践的 Java 示例资源,适合已经具备 Spring Boot 基础、希望系统掌握接口文档生成与规范化的后端开发者。内容以可运行演示的方式覆盖依赖接入、OpenAPI 配置、@Operation 与 @ApiResponse 等注解使用、请求体与响应描述、GroupedOpenApi 分组、Spring Security 安全需求以及 Swagger UI 调试等典型场景,并演示 OAuth2、API 密钥等认证机制的表达,帮助读者把分散接口整理为清晰可维护的交互式文档。压缩包共219个文件,以139个 Java 源码为核心,辅以23个 XML、21个 YML 配置及少量 Markdown、properties、JSON 和 SQL 文件,整体约281KB,体积轻便但结构较完整,便于按模块查阅和本地验证。目前已有967人学习下载。对需要快速搭建 OpenAPI 3 示例、对照注解写法、梳理 API 分组与安全配置的读者来说,这份资源可作为从配置到文档呈现的实践参考,目录按示例模块拆分,也便于团队内部接口规范化讨论。

1. 从一份能点开的接口文档说起:springdoc-openapi-demos 到底演示了什么

接手一个跑了三年多的 Spring Boot 服务,前端来问某个字段到底能不能为空,你翻半天 Controller,注释早过期了——这种场景我遇到过不止一次。springdoc-openapi-demos 就是解决这个问题的:它是一组用 Java 写的 Spring Boot 演示工程,把 springdoc-openapi 在 Spring MVC、WebFlux、Spring Boot 1.x、Kotlin 这几种形态下的接法各跑一遍,启动后直接产出符合 OpenAPI 3 规范的 JSON 和一份 Swagger UI 页面,不用手写一行 YAML。适合两类人:一类是刚要给项目补接口文档、又不想上 Springfox 的后端;另一类是想搞清楚「注解到底落到了 spec 的哪个字段上」的平台或中间件开发者。它不解决业务问题,解决的是接口契约的可读性和可验证性——把这份 demo 跑通,你基本就知道自己项目该怎么接、哪些坑要提前绕。

2. 工程结构与依赖矩阵:四个子模块分别在验证哪种 Spring Boot 形态

2.1 从根 pom 到各演示子模块

下载下来解压第一眼看到的不是某个src目录,而是根目录一个packaging=pom的聚合工程,下面挂着若干平级的子模块。这个组织方式不是随便定的:Spring Boot 1.x 和 2.x 的 classpath 天生互斥,WebMvc 和 WebFlux 的运行模型也不一样,硬塞进一个 module 里,依赖冲突能让你调到怀疑人生。所以它选择「一个形态一个模块」,各自独立mvn spring-boot:run,互不干扰。

结构大致是这样,不同分支或版本里子模块数量会有增减,以你手上那份根pom.xml的<modules>为准:

springdoc-openapi-demos/ ├── pom.xml # 聚合 POM,packaging=pom,统一管 springdoc 版本 ├── springdoc-openapi-demo/ # 经典 Spring MVC:spring-boot-starter-web │ ├── pom.xml │ └── src/main/java/.../SpringDocDemoApplication.java │ # controller / model / config 分三包 ├── springdoc-openapi-demo-webflux/ # 响应式栈:spring-boot-starter-webflux │ └── src/main/java/.../ # RouterFunction 与 @RestController 两种写法都有 ├── springdoc-openapi-demo-spring-boot-1/ # Boot 1.x 兼容演示,验证老项目的接法 └── springdoc-openapi-demo-kotlin/ # Kotlin 语言版本,验证注解在 Kotlin 下的解析

根 POM 里通常用<dependencyManagement>统一声明springdoc-openapi-*的版本,子模块只写groupId+artifactId,不写版本号。这个细节看起来很琐碎,但它是你能安全升级的前提:springdoc 和 swagger-core 的版本是绑死的一对,散落在各个子模块里手写版本,迟早会出现一个模块能跑、另一个模块启动就 NPE 的局面。

我一般接手别人的多模块工程会先干三件事:mvn -q dependency:tree -Dincludes=org.springdoc看版本有没有被传递依赖顶掉;确认每个子模块的server.port不一样,避免同时启动打架;再看根 POM 有没有配maven-compiler-plugin的<release>,因为 Java 8 和 17 编译出的字节码在注解保留策略上没差别,但 Kotlin 模块的jvmTarget一定要对齐。

2.2 依赖矩阵:选错坐标是新手第一个坑

springdoc 在不同 Spring Boot 世代下坐标是不一样的,这份 demo 最大的价值之一就是把这几套坐标都摆出来了:

运行形态依赖坐标说明
Spring MVC(Boot 2.x)org.springdoc:springdoc-openapi-ui会传递引入 swagger-ui 的 webjar,自带页面
Spring WebFlux(Boot 2.x)org.springdoc:springdoc-openapi-webflux-ui响应式栈专用,扫描的是RouterFunction和@RestController
Spring Boot 1.xorg.springdoc:springdoc-openapi-spring-boot-1兼容老启动器,自动配置走spring.factories
Spring MVC(Boot 3.x)org.springdoc:springdoc-openapi-starter-webmvc-ui2.x 起坐标重命名,基于jakarta.*

注意最后一行。Boot 3 把javax.servlet换成了jakarta.servlet,1.x 版本的 springdoc 整个自动配置类都基于javax写,装上去编译能过,但自动配置条件不满足,结果是启动成功、接口正常、文档页面 404,控制台一条错误都不报。这种「静默失败」最难受,新手很容易在这上面耗掉一整个下午。常见做法是:先看spring-boot-starter-parent的版本,2.x 用springdoc-openapi-ui,3.x 用springdoc-openapi-starter-*-ui,两边不要混。

另外,只有-ui后缀的包才会带 Swagger UI 页面。如果你只想要/v3/api-docs的 JSON、页面交给前端独立部署,那就用不带-ui的springdoc-openapi-webmvc-core一类坐标,产物体积能小一截。这是上线环境里我比较推荐的做法:文档页面本身也是攻击面,生产环境直接关掉 UI、只留 JSON,让文档平台去拉。

2.3 三个地址:JSON、YAML 和页面

启动之后能访问的入口就三个,记住了基本不会迷路:

  • /v3/api-docs—— OpenAPI 3 的 JSON,一切的核心,UI 页面也是拉它渲染的;
  • /v3/api-docs.yaml—— 同一份内容的 YAML 序列化,给习惯读 YAML 的人用;
  • /swagger-ui/index.html—— 页面本体,老版本的/swagger-ui.html会做一次 302 跳转过去。

这里有个容易被忽略的机制:UI 页面不是把 spec 硬编码进去的,它在浏览器里再发一次请求去拿/v3/api-docs。所以只要你在application.yml里改了springdoc.api-docs.path,UI 会自动跟着改,不用两边同步。但反过来,一旦中间隔了 Nginx 或者网关,页面能打开、spec 拉不到,八成就是这条二次请求被拦了——第 5 章会细说。

3. 跑通链路:从 mvn spring-boot:run 到 curl 拿到 openapi.json

3.1 环境准备与启动命令

JDK 版本按模块选:MVC 和 WebFlux 模块 JDK 8 就能跑,Kotlin 模块建议 11 以上,Boot 1.x 那个模块只能用 JDK 8,放到 17 上会因为反射访问限制直接起不来。Maven 用 3.6 以上,够用。

在根目录执行带-pl的单模块启动,别在根目录直接mvn spring-boot:run,聚合工程没有主类,会报错:

# 先整体编译安装到本地仓库,子模块之间若有依赖才能解析 mvn -q clean install -DskipTests # 只启动经典 MVC 演示模块 mvn -pl springdoc-openapi-demo spring-boot:run # WebFlux 模块换个端口起,避免和上面那个抢 8080 mvn -pl springdoc-openapi-demo-webflux spring-boot:run \ -Dspring-boot.run.arguments=--server.port=8081

-pl后面跟的是模块目录名,-Dspring-boot.run.arguments是给spring-boot-maven-plugin传运行参数的官方姿势,等价于在命令行里追加--key=value。有人习惯直接java -jar target/xxx.jar --server.port=8081,也行,前提是 POM 里配了spring-boot-maven-plugin的repackage,否则打出来的 jar 没有主清单,java -jar会提示 no main manifest attribute。

启动日志里会有一行Tomcat started on port(s): 8080或者Netty started on port(s): 8081,看到这行就说明容器起来了。注意 WebFlux 模块打的是 Netty 不是 Tomcat,日志关键词不一样,别以为没起来。

3.2 用 curl 做契约冒烟测试

页面点开看一眼只是「看起来跑通了」,真正的验证是把 spec 拉下来做结构化断言。我习惯用 curl 配 jq,三行搞定:

# 1) 确认返回的是 OpenAPI 3,而不是 Swagger 2.0 curl -s http://localhost:8080/v3/api-docs | jq -r '.openapi' # 期望输出 3.0.x 或 3.1.x # 2) 列出所有被扫描到的路径,确认业务接口一个没漏 curl -s http://localhost:8080/v3/api-docs | jq -r '.paths | keys[]' # 3) 检查某个路径下 GET 的响应码定义是否齐全 curl -s http://localhost:8080/v3/api-docs \ | jq '.paths["/api/books/{id}"].get.responses | keys'

第一条如果输出的是2.0,说明 classpath 里混进了 Springfox 或者老的 swagger 依赖,/v3/api-docs被另一个实现接管了。第二条是排查「接口写了但文档里没有」的最快手段,通常是 Controller 不在扫描包范围内,或者被@Hidden挡了。第三条用来查响应码:一个只写了@GetMapping没写@ApiResponse的接口,responses里只会有一个自动推导出来的200,404、500这些业务上真实存在的分支是缺失的。

把这三条命令塞进 CI 的冒烟脚本,每次打包前跑一遍,比人肉点页面靠谱得多。文档漂移这种事,靠自觉是防不住的。

3.3 application.yml 里必须改的几个开关

demo 默认配置能跑,但落到自己项目上,下面这几个开关基本都要动:

springdoc: api-docs: path: /v3/api-docs # 改路径的话,网关白名单要同步改 enabled: true # 生产环境可以设 false,只留构建期导出 swagger-ui: path: /swagger-ui.html # 页面入口,实际会 302 到 /swagger-ui/index.html operations-sorter: method # 按 GET/POST 排,比按字母排好用 tags-sorter: alpha disable-swagger-default-url: true # 关掉默认的 petstore,避免页面加载外部资源 packages-to-scan: com.example.demo # 限定扫描包,大项目能明显缩短首次构建时间 paths-to-match: /api/** # 只暴露业务前缀,把 actuator 等挡在外面 default-produces-media-type: application/json

packages-to-scan和paths-to-match是两个不同的维度:前者按类的包路径过滤,后者按 URL 过滤,两个都配就是取交集。项目大了以后不配这两个,首次访问/v3/api-docs会明显卡顿,因为 springdoc 要把容器里所有RequestMappingHandlerMapping注册的 handler 全扫一遍,再逐个解析泛型和方法签名。我见过一个中台项目不配扫描范围,冷启动后第一次拉文档要等七八秒,配上之后降到一秒以内。

disable-swagger-default-url这个开关值得单独说一句。它关掉的是 UI 页面加载时默认去拉的那份远程 petstore 示例,如果不关,内网环境下页面会先卡在那儿等超时,看起来像「文档服务挂了」,其实只是 UI 在等一个访问不到的外网地址。

4. 核心代码拆解:一个 BookController 是怎么被翻译成 OpenAPI 3 文档的

4.1 启动类与自动配置链路

演示模块的启动类干净得有点过分,除了@SpringBootApplication什么都没加:

// 演示模块的启动类:文档能力全部来自 starter 的自动配置 @SpringBootApplication public class SpringDocDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringDocDemoApplication.class, args); } }

真正干活的是依赖里那个 starter。它在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Boot 2.7+ / 3.x)或老的spring.factories里登记了一组配置类,核心是三个角色:一个负责往容器里注册/v3/api-docs的 handler(MVC 走@RestController,WebFlux 走RouterFunction);一个负责把springdoc.*前缀的配置绑定成SpringDocConfigProperties;还有一个OpenAPIService负责实际的文档构建。

关键点在于「懒构建」。/v3/api-docs对应的方法不是启动时就把文档算好,而是第一次被请求时才去扫 handler、拼 schema,然后把结果缓存起来。所以你在启动日志里看不到任何「文档生成完成」的字样,这是正常的,别以为没生效。反过来,如果你在运行期动态注册了新的RequestMapping,缓存不会自动失效,需要重启或者手动调OpenAPIService清一下——这也是很多人反馈「新加的接口文档里没有」的真实原因之一。

4.2 控制器上的注解:@Operation、@Parameter、@ApiResponse

这是整份 demo 里最值得逐行看的部分,一个方法上的四个注解,分别落到 spec 的四个不同层级:

@RestController @RequestMapping("/api/books") @Tag(name = "图书管理", description = "图书的增删改查") // 落到 spec 顶层 tags 数组 public class BookController { private final BookService service; public BookController(BookService service) { this.service = service; } @Operation(summary = "按 ID 查询图书", // 落到 operation.summary description = "查不到时返回 404 与错误体") // 落到 operation.description @ApiResponses({ @ApiResponse(responseCode = "200", description = "查询成功"), @ApiResponse(responseCode = "404", description = "图书不存在", content = @Content(schema = @Schema(implementation = ApiError.class))) }) @GetMapping("/{id}") public Book get( @Parameter(description = "图书主键", example = "1") // 只作用于当前参数 @PathVariable Long id) { return service.findById(id); } }

@Tag是类级别的,它决定 UI 页面上这个接口被折叠到哪个分组下面;多个 Controller 写同一个name就会被合并到一组。@Operation是方法级别的摘要,operationId不写的话 springdoc 会用方法名自动生成,生成客户端 SDK 时这个名字就是方法名,所以我在需要出 SDK 的项目里会显式写operationId,避免重构改方法名把下游代码全打断。

@Parameter只影响当前这一个参数,跟@PathVariable、@RequestParam是叠加关系,不是替代关系——把 Spring 的绑定注解去掉只留@Parameter,运行期直接绑不上参数,这个错误我在 review 时见过不止一次。@ApiResponse里的content更是个高频遗漏点:不写content只有描述文字,写了才会在 spec 里生成对应的 schema,前端才能拿到错误体的字段结构。

4.3 模型层的 @Schema 与泛型返回体

实体类上的注解决定了components.schemas长什么样:

@Schema(description = "图书实体") public class Book { @Schema(description = "主键,服务端生成", example = "1", accessMode = Schema.AccessMode.READ_ONLY) // 请求体里不出现,响应体里出现 private Long id; @Schema(description = "书名", example = "分布式系统设计", requiredMode = Schema.RequiredMode.REQUIRED) private String title; @Schema(description = "价格,单位:分", example = "1990") private Integer priceInCents; @Schema(description = "上架时间", type = "string", format = "date-time") private LocalDateTime publishedAt; // getter / setter 省略 }

accessMode = READ_ONLY这个属性特别实用:它让同一个类在「新增请求体」和「查询响应体」两个场景下呈现出不同的字段集,不用为了区分读写去建两个 DTO。requiredMode是 swagger-core 较新版本的写法,老版本上是required = true,两者不要混用,混用的话编译能过但只有一个生效。

返回值是泛型容器时要多留个心。ResponseEntity<Page<Book>>这种写法,springdoc 会尝试把Page展开成一个带content、totalElements的对象,命名规则是PageOfBook一类的拼接形式。如果展开得不理想,可以在方法上补@ApiResponse(content = @Content(schema = @Schema(implementation = BookPage.class)))强制指定,自己写一个扁平的BookPage类,前端对接起来反而更省事。分页参数Pageable则建议加@ParameterObject,否则它会以page、size、sort三个散装参数的形式平铺出来,字段名丑但能用。

4.4 自定义 OpenAPI Bean:全局信息与鉴权方案

扫描出来的路径和模型是「自动」的部分,全局的标题、版本、鉴权方式得自己声明:

@Configuration public class OpenApiConfig { @Bean public OpenAPI demoOpenAPI() { return new OpenAPI() .info(new Info() .title("图书服务 API") .version("v1") .description("内部服务,鉴权走 Bearer Token")) // 给所有接口挂上同一个安全要求 .addSecurityItem(new SecurityRequirement().addList("bearerAuth")) .components(new Components().addSecuritySchemes("bearerAuth", new SecurityScheme() .type(SecurityScheme.Type.HTTP) .scheme("bearer") .bearerFormat("JWT") .description("请求头传 Authorization: Bearer <token>"))); } }

这个 Bean 的角色是「基线」:springdoc 扫描出来的 paths、schemas 会和它合并,你写的info、servers、securitySchemes会被保留。所以别在这个 Bean 里手写 paths,写了也不会覆盖扫描结果,反而容易让人误以为文档是手工维护的。

addSecurityItem是全局生效的,意味着每个接口在 UI 上都会出现那把锁。如果只有部分接口需要鉴权,就别在全局加,改成在具体方法上用@SecurityRequirement(name = "bearerAuth")单独标注。这个区别不大但影响很大:全局加了以后,公开的健康检查接口在 UI 上也被标成需要 token,对接方会来问你是不是配错了。

4.5 GroupedOpenApi:一个服务拆出多份文档

单体应用接口上百个之后,所有人挤在一份文档里翻,体验很差。demo 里演示了分组能力:

@Bean public GroupedOpenApi adminApi() { return GroupedOpenApi.builder() .group("admin") // 访问路径变成 /v3/api-docs/admin .pathsToMatch("/api/admin/**") // 按 URL 前缀切 .packagesToScan("com.example.demo.admin") // 再叠加包路径过滤 .addOpenApiCustomizer(openApi -> openApi.info(new Info().title("管理端 API").version("v1"))) .build(); }

声明之后,/v3/api-docs/admin就是独立的一份 spec,UI 页面右上角会出现一个分组下拉框,可以切换查看。addOpenApiCustomizer是在合并完成之后执行的钩子,适合改info、追加servers、批量给路径打 tag。要注意每个分组的group名字不能重复,重复了启动时就抛异常,而且异常信息不太直观,只说 bean 冲突。

分组策略上我的建议是按「消费方」切而不是按「代码包」切:给 Web 前端一组、给开放平台一组、给内部运维一组,比按controller.admin、controller.portal这种技术分包切更贴近实际使用。

5. 避坑与排查:404、401、NPE 这几种翻车现场

5.1 访问 /v3/api-docs 返回 404,控制台一条错误都没有

现象:应用启动正常,业务接口能调通,就是文档地址 404,日志安静得可疑。

原因:最常见的是 Spring Boot 3.x 配了 1.x 的依赖坐标。1.x 的自动配置类基于javax.servlet,Boot 3 的容器里没有这套类,条件装配直接不满足,配置类压根没加载。其次是server.servlet.context-path被设成了/api,真实地址变成了/api/v3/api-docs,而你在浏览器里访问的是根路径。

解决:先确认依赖坐标和 Boot 大版本对得上;再用--debug启动,在ConditionEvaluationReport里搜SpringDoc看条件为什么没匹配;最后检查context-path和网关的路径重写规则。我一般会先curl -i看返回码,404 和 401 是完全不同的问题方向,别一上来就翻源码。

5.2 启动直接 NPE,栈里能看到 PathPatternParser

现象:应用起不来,或者起来后第一次访问文档就空指针,异常栈里出现org.springframework.web.util.pattern.PathPatternParser或AntPathMatcher。

原因:Spring Boot 2.6 起把默认路径匹配策略从AntPathMatcher换成了PathPatternParser,老版本 springdoc 里有一部分逻辑还在按 Ant 的语义解析路径,两边对不上就炸。

解决:首选升级 springdoc 到与 Boot 版本匹配的版本,这是根治。临时方案是在配置里退回旧策略:

spring: mvc: pathmatch: matching-strategy: ant_path_matcher # 治标:退回旧匹配器

注意这是治标,退回之后PathPatternParser带来的一些性能优化和语法能力就没了,只能当过渡。血泪经验是:升级依赖之前先看 release notes 里的兼容矩阵,别凭感觉挑版本号。

5.3 页面能打开但一片空白,提示 Failed to load API definition

现象:/swagger-ui/index.html能加载出框架,中间区域空白,右上角弹红色提示,浏览器 Network 里能看到/v3/api-docs请求失败。

原因:三种可能。一是 Spring Security 把/v3/api-docs/**拦了,返回 401 或 403;二是改了springdoc.api-docs.path但网关白名单还是老路径;三是反向代理只转发了/swagger-ui前缀,没转发/v3/api-docs。

解决:Security 配置里显式放行文档相关路径:

http.authorizeHttpRequests(auth -> auth .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll() .anyRequest().authenticated());

如果是代理问题,用springdoc.swagger-ui.url直接写绝对地址,让浏览器跳过相对路径推导,比改代理规则快。这个字段一设,UI 就不再去猜 spec 地址了。

5.4 点 Try it out,请求打到了 localhost:8080 而不是网关域名

现象:文档部署在https://docs.example.com,点「试一试」发出去的请求却指向http://localhost:8080/api/...,直接失败。

原因:UI 默认用当前页面的 origin 拼接请求地址;如果 spec 里没有servers,或者代理没有透传X-Forwarded-Host、X-Forwarded-Proto,后端拿到的就是内网地址。

解决:在OpenAPIBean 里显式声明servers,或者在代理层补齐转发头并开启server.forward-headers-strategy=framework。前者更可控,我一般直接写死生产域名,反正文档通常只在特定环境开放。

5.5 文档和实际返回对不上,字段名、可空性全是错的

现象:前端照着文档写解析逻辑,联调时字段对不上;或者文档里某个字段标了必填,实际接口允许为空。

原因:注解写完之后没人验证,代码改了注解没改。更隐蔽的一种是@Schema(implementation = X.class)指错了类,编译期完全无感;还有泛型被擦除导致 schema 退化成一个空对象。

解决:把契约纳入 CI。每次构建拉一次/v3/api-docs,用 jq 或 JSON Schema 断言做关键字段校验;发版前把 spec 存成文件做 diff,变了就要求提交人说明。第 6 章会给一个构建期导出的配置,配合这个流程能挡住大部分漂移。

6. 二次开发:把 demo 里的写法沉淀成团队的文档流水线

demo 跑通只是起点,真正要解决的是「怎么让几十个服务都稳定产出可信的 spec」。我踩过的坑里,最值钱的一条是:注解写得再全,没有自动化兜底,三个月后一定漂移。

第一个改造点是统一注入公共信息。与其每个 Controller 手写traceId请求头和统一错误体,不如挂一个OperationCustomizer,全局生效:

@Bean public OperationCustomizer globalHeaderCustomizer() { return (operation, handlerMethod) -> { // 给每个接口补一个 traceId 请求头,前端和网关对齐用 operation.addParametersItem(new Parameter() .in("header").name("X-Trace-Id") .description("链路追踪 ID,不传则服务端生成") .required(false).schema(new StringSchema())); return operation; }; }

这个钩子对每个HandlerMethod执行一次,比在几百个方法上贴同一段注解靠谱得多,新增接口自动继承。

第二个改造点是构建期把 spec 固化成文件,不依赖运行中的服务:

<!-- pom.xml 片段:打包时导出 openapi.json,交给 CI 做契约比对 --> <plugin> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-maven-plugin</artifactId> <configuration> <apiDocsUrl>http://localhost:8080/v3/api-docs</apiDocsUrl> <outputFileName>openapi.json</outputFileName> <outputDir>${project.build.directory}</outputDir> </configuration> <executions> <execution> <id>integration-test</id> <phase>integration-test</phase> <goals><goal>generate</goal></goals> </execution> </executions> </plugin>

它在integration-test阶段启动应用、拉一次 spec、写盘、再关掉。产出的openapi.json直接进制品库,前端可以用它生成 SDK,测试可以用它做 mock server,网关可以用它做路由校验。这比让人去页面点「下载 JSON」然后手工传群文件,稳定性高了不止一个量级。

第三个改造点是分组和网关前缀对齐。服务部署在网关后面统一带/book-service前缀时,spec 里的 paths 也得跟着带,否则前端生成的请求地址全错。做法是在GroupedOpenApi的 customizer 里批量重写 path,或者干脆在OpenAPIBean 里设servers,让客户端自己拼前缀——后者更简单,我倾向于这个。

验证方法很朴素:改完之后跑一次第 3 章那三条 curl,再看构建产物里的openapi.json有没有按预期变化,最后拿生成的前端 SDK 编一遍。三层都过,才算改完。

从那以后我每次接手新服务,第一件事都是把/v3/api-docs拉下来存一份基线,之后每次改接口都跟基线 diff 一遍,多出来的、少掉的、字段类型变了的,必须有人解释。文档这东西,写的时候是负担,出事的时候是唯一的后悔药。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询