1. 先理解 ShowDoc 在 Spring Boot 开发里到底是什么角色做后端最烦的事情里,维护接口文档绝对能排进前五。我之前在某团队接手一个订单服务,代码里接口全有,但文档还停留在上一任同事离职前的 Word 版本,前端联调时对着旧文档问"这个参数明明没传啊",我一看代码,字段早改名了。就是从那时候开始,我把 Spring Boot API 接口文档的维护方式换成了 ShowDoc。这篇东西不是官方教程,是我从部署到落地,再到团队一起用起来的全过程记录,适合正在纠结"要不要上文档工具"的后端开发,也适合刚把 ShowDoc 装起来但不知道怎么接入 Spring Boot 的读者。1.1 ShowDoc 到底是个什么工具ShowDoc 从产品形态上说是一个私有化、可部署的在线文档系统。它最大的特点不是"生成接口文档",而是"什么文档都能往里放"。你可以新建一个接口项目,用 Markdown 或富文本维护每个接口的 URL、header、请求体、返回示例、错误码;也可以另开一个目录,把数据库字段字典、环境配置说明、部署手册全部整理进去。对 Spring Boot 项目来说,一个好的接口文档工具需要满足三个条件:第一,能承载自动生成的内容;第二,能支持团队在线编辑和评论;第三,能控制访问权限。ShowDoc 恰好三点都占。它不像 Swagger UI 那样只能展示 Swagger 注解生成的结果,也不像某些以调试为核心的工具那样只注重"能不能调通",它更像一个围绕接口资料的"内部 Wiki",接口信息只是其中一类页面。1.2 和 Word、Swagger UI 的真实对比我在实际项目里用过 Word、Swagger UI、ShowDoc 三种方式,体验差别很大。Word 文档的问题是完全没有强约束。谁改了代码不更新 Word,没人知道;多人同时编辑时版本互相覆盖;文档里写"详见 XX 文档"最后根本找不到。Swagger UI 的问题是"能看不能用"。它确实能根据注解实时生成接口列表,也能在线调试,但字段说明、业务含义、错误码意思、数据字典这些靠注解很难写清楚,而且一旦项目多了,Swagger UI 的导航会变得非常难用,还经常遇到跨域问题。ShowDoc 的价值在于把这几种工具的长处合到一起:接口列表从 OpenAPI 数据导入,字段说明、错误码、更新记录靠编辑页面补充,访问权限按项目划分,历史版本还能找回。我用下来最直观的感受是:前端拿到的不再是一堆 JSON schema,而是一份他们自己能看懂的"接口使用说明"。1.3 哪些项目适合选 ShowDoc不是所有团队都适合。如果是单机小 Demo,直接看 Swagger UI 就够;如果团队规模很大,已经在用一体化 API 管理平台,也没必要再引入 ShowDoc。ShowDoc 最合适的场景是:接口数量中等(几十到几百个)、前后端协作流程还没完全规范化、需要把接口文档放在公司内网、还需要有人能编辑权限的团队。我现在的团队就是用 Spring Boot 做微服务,每个服务一个工程,ShowDoc 按服务建项目,实践了半年,效果比之前好太多。2. 部署 ShowDoc 服务:我推荐私有化 Docker 方案ShowDoc 官方提供在线版,但介于接口文档通常带有业务信息,我不太建议把公司内部接口丢给第三方。私有化部署是最稳妥的选择,而 Docker 方案最省心。2.1 一条命令跑起来如果你服务器上已经装好 Docker,启动 ShowDoc 其实就是一句命令:docker run -d \ --name showdoc \ --restart=always \ -p 4999:80 \ -v /data/showdoc_data:/var/www/html/ \ showdoc/showdoc这条命令做了三件事:把容器命名为 showdoc,方便后续查看日志和启停;用--restart=always保证服务器重启后容器自动拉起;把宿主机的/data/showdoc_data目录挂载到容器 Web 根目录,这样文档数据不会随容器删除而丢失。启动完成后访问http://服务器IP:4999,走完初始化引导,用默认管理员账号登录并立即改掉密码。这里特别提醒,默认端口 80 被很多人挂在公网上扫到过,建议改成不常用端口,再配合防火墙只放行内网 IP 访问。2.2 数据备份恢复的完整做法ShowDoc 的数据存在 MySQL 和文件目录里,容器化部署后这些底层细节被隐藏了,我们只要保证挂载目录安全就行。我的备份策略很简单:每天凌晨压缩整个挂载目录,保留最近 7 天。tar -czf /backup/showdoc_$(date +%F).tar.gz -C /data showdoc_data find /backup -name "showdoc_*" -mtime +7 -exec rm -f {} \;恢复操作也直接:新服务器上把备份文件解压到同样的/data目录,再跑一遍 docker run 命令,数据就回来了。我踩过一次坑,是早期没意识到挂载目录的重要性,升级容器时直接删了容器,数据全丢。后来所有 docker run 都带上-v挂载,这个教训比任何配置都重要。2.3 项目和权限规划要提前做ShowDoc 安装好后第一件事不是写接口,而是规划项目结构。我建议按"服务域"建项目,比如用户服务、订单服务、商品服务,而不是把所有接口混到一个项目里。一个项目对应一个 ShowDoc 项目,权限好控制,文档也好维护。在 ShowDoc 后台,项目可以设置为私有项目,然后手动添加成员。角色我习惯只开两种:后端主程是编辑者,其他人是只读成员。前端同学一般不需要编辑权限,他们需要的只是稳定的只读地址。如果遇到要临时修改文档的情况,再提升权限,避免误操作污染文档。这一步看似简单,但对后面的自动化同步很关键,因为权限规划直接决定 API Key 的使用范围。3. Spring Boot 接入 ShowDoc:核心是把 Swagger JSON 变成同步任务ShowDoc 有一个很实用的能力:对外开放接口,允许你把外部系统生成的文档内容直接写入指定项目。这就给 Spring Boot 项目提供了一个自动化方案:用 SpringDoc 生成 OpenAPI JSON,再把 JSON 转成 ShowDoc 需要的页面结构,最后通过 ShowDoc 开放接口推送上去。3.1 为什么中间格式选 OpenAPI 而不是直接手写市面上很多人误以为"用 ShowDoc 就等于放弃 Swagger"。实际上两者是配合关系。Spring Boot 项目里通过注解维护接口信息,SpringDoc 会自动生成/v3/api-docs的 OpenAPI JSON。这个 JSON 是标准格式,包含接口路径、方法、参数、响应体和说明。ShowDoc 支持导入 OpenAPI 格式数据,也支持用开放接口创建页面。我之所以选择 OpenAPI 作为中间层,是因为它"两边不吃亏":开发时用注解,IDE 能检查;文档更新时由脚本把 JSON 转换推送,不用人去一个个复制参数。如果哪一天团队决定换文档工具,OpenAPI JSON 还能继续导入别的平台,数据不会被绑死。3.2 Spring Boot 侧配置 SpringDoc在 Spring Boot 工程里加入 springdoc-openapi 依赖后,它自动扫描 Controller 上的注解。下面是基础配置:springdoc: api-docs: enabled: true path: /v3/api-docs swagger-ui: path: /swagger-ui.html启动项目后访问http://localhost:8080/v3/api-docs,能看到一个很大的 JSON,这就是 OpenAPI 数据。为了让这个 JSON 内容够完整,Controller 类和方法上的注解要写全,稍后我会在第四节专门讲字段规范。这里先记住一个原则:注解里写清楚的内容,会原样进入 ShowDoc,注解里没有的内容,后面就得靠手工补,工作量大得多。3.3 同步服务的核心代码ShowDoc 的开放接口逻辑是:准备好 API Key、API Token、项目 ID,然后把文档内容 POST 上去。不同部署地址的开放接口路径可能不一样,去后台的"开放 API"页面能看到当前地址对应的示例。我封装的同步服务简化后是这样:@Service public class ShowDocSyncService { private final RestTemplate restTemplate = new RestTemplate(); @Value("${showdoc.api-url}") private String apiUrl; @Value("${showdoc.api-key}") private String apiKey; @Value("${showdoc.api-token}") private String apiToken; @Value("${showdoc.item-id}") private String itemId; public void syncFromSwagger(String swaggerJson) { // 这里把 OpenAPI JSON 转换成 ShowDoc 的目录和页面结构 // 推荐的做法是遍历 paths 节点: // 每个 tag 作为一个目录,每个 path+method 作为一个页面 List<Map<String, Object>> catalogs = Converter.toShowDocPages(swaggerJson); MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("api_key", apiKey); params.add("api_token", apiToken); params.add("item_id", itemId); params.add("data", JacksonUtils.toJson(catalogs)); ResponseEntity<String> response = restTemplate.postForEntity(apiUrl, params, String.class); // 判断 response body 中的状态,失败则抛出异常 } }这个类的重点在Converter.toShowDocPages,它负责把 Swagger JSON 里的paths和tags映射成 ShowDoc 页面层级。比如一个"用户管理" tag 下有三个接口,最终在 ShowDoc 里就是一个"用户管理"目录,下面挂着三个接口页面。转换逻辑不难,但要注意几个问题。第一,OpenAPI 里同一个 path 可能对应多个 HTTP 方法,比如/user/{id}有 GET 和 PUT,页面标题要带上[GET]前缀,否则同名页面会互相覆盖。第二,ShowDoc 的页面内容是 Markdown,转换时要把请求体、响应体、参数表转成 Markdown 表格,才能保证前端阅读体验。第三,不要把所有接口塞到一个页面,按接口页面拆分,方便单独维护。3.4 触发方式:手动按钮 + CI 自动同步同步代码写好后,触发方式我推荐两个层面。开发阶段,写一个 Spring Boot 单元测试或一个ApplicationRunner,启动时打一个开关,需要时手动调用 sync 方法。发布阶段,在 CI 构建脚本里加一段请求,让测试通过后自动执行同步。# 假设同步服务本身也暴露了一个受保护的 HTTP 接口 /sync/api-docs curl -X POST http://localhost:8080/sync/api-docs \ -H "Content-Type: application/json" \ -d '{"secret":"your-sync-token"}'这里有一个特别容易踩的坑:同步接口不要不加保护地暴露到公网。用 ShowDoc 开放接口时,API Token 本身是一个高权限凭据,任何拿到它的人都能直接修改文档。所以代码仓库里绝对不能提交真实 token,要用环境变量注入,同步接口也要加一层自己的签名。4. 让文档真正好用:接口内容规范比工具选型更重要我见过不少团队,工具从 Word 换到 ShowDoc,文档还是一团糟。原因很简单,工具解决的是"放哪",不解决"写什么"。Spring Boot 接口文档要让人愿意看,核心是把字段、返回值、错误码这三件事说清楚。4.1 统一返回结构,文档里只放一个真实示例很多 Spring Boot 项目用Result<T>包一层,这没问题,但接口文档里最常见的错误是:所有接口的返回示例都写成{code:0, message:"成功", data:{}},data 里面到底长什么样完全没说。前端拿到这种文档还是得来问你。我的习惯是,在 Controller 的注解里直接用具体响应对象,让生成的 OpenAPI JSON 里能看到 data 的结构。比如:@Operation(summary = "查询订单详情") @GetMapping("/order/{id}") public Result<OrderDetailVO> getOrder(@PathVariable Long id) { return Result.success(orderService.getDetail(id)); }然后在OrderDetailVO的每个字段上写@Schema(description = "订单状态:0-待支付,1-已支付,2-已取消")。这样 Swagger JSON 里的字段说明完整,同步到 ShowDoc 后前端就能直接看到 data 结构,而不是一个空的{}。4.2 字段说明的五个必填项写字段说明时,我要求团队每个字段至少回答五个问题:字段名是什么;类型是什么(string / integer / boolean / object / array);是否必传;取值范围或枚举含义;一个真实可用的示例值。举个例子,订单状态如果只写"状态"两个字,前端大概率搞不清楚;如果写成"订单状态,可选值:1待支付、2已支付、3已取消,示例:2",联调效率会高很多。这些内容都可以直接写在@Schema注解里。需要注意,注解里的example属性会进入 OpenAPI JSON,ShowDoc 转换后也可以保留,所以示例值一定要填,别嫌麻烦。4.3 错误码单独维护一个页面HTTP 状态码和业务错误码是两码事。很多接口返回 HTTP 200,但业务 code 是 10001 表示"订单不存在"。如果文档里不把业务错误码列清楚,前端同事只能靠猜。我在 ShowDoc 项目里固定建一个"错误码说明"目录,用 Markdown 表格维护所有业务 code、含义、建议处理方式。这个目录用脚本自动同步时不要覆盖,保留给人工维护。错误码的规范要用排除法:所有接口共用一个 code 字段,不要某个接口返回success、另一个接口返回status,这种不一致是文档大忌。4.4 目录结构要有头脑,不要全部堆在顶层ShowDoc 的项目页面是按目录组织的。目录建议按"业务模块"而不是"Controller 类"来建。比如订单服务下面分"订单查询""订单操作""售后流程",这样前端按业务场景找接口,比按类名一个一个翻要快。另外,我会给每个模块目录配一个"使用说明"页面,写清楚这个模块的业务背景、通用 header、必填 token、分页规则。这类页面用自动化脚本创建一次就不动了,后续手工补充。把"自动同步生成的页面"和"手工维护的页面"分开,是防止脚本覆盖人工内容的最后一道防线。5. 团队协作中真正提升效率的四个习惯ShowDoc 安装后如果只是一个人上传文档,那它只是一个网盘。要让它发挥价值,必须把它嵌进团队的工作流里。5.1 访问权限要分清,API Key 也要分级别给前端同学分配只读账号,而不是把项目链接直接扔到群里让大家匿名访问,这是我对团队的最低要求。只读账号的好处是可追溯、可撤销,新人进来给他开账号,有人离职直接禁用,不用换整个项目链接。对自动化同步用的 API Key 也要单独建一个"机器人"账号,不要拿管理员的 Key 去写脚本。这样就算脚本里的 Key 泄露,权限只影响指定项目,不会波及整个 ShowDoc 服务。这个问题容易被忽视,我见过有团队把管理员 token 直接写在前端代码里,最后整个文档库都被人清空了。5.2 Mock 数据与并行开发后端接口还没写完时,前端最痛苦的是没有数据可以联调。ShowDoc 的页面内容本身就是 Markdown,可以在里面维护一份完整的返回示例,前端照着示例写死数据先开发页面。等后端好了再切换真实接口,大部分逻辑不用改。这个方法比单独搭 Mock 服务更轻量。我在实践中的体会是,Mock 服务适合接口数量大、团队已经有一套流程的场景;而 ShowDoc 加"约定返回示例"的方式,适合中小团队让前后端先对齐数据结构。关键点在于,返回示例必须写的是"真实数据结构",不能为了示例好看而编一个和实际代码不一致的字段。否则前端按示例写的数据结构到了联调阶段全部要返工,比没有 Mock 更糟。5.3 把文档更新动作放进发布流程最容易老化的文档就是"没人主动去更新"的文档。我现在要求:只要后端接口有变更,代码合并之前必须把同步脚本跑一遍。这样才能保证线上文档和代码是同一版本。你在 CI 里加一个步骤,构建成功后调用同步接口,发布没成功文档就不会更新,这个联动帮团队省了很多心。CI 脚本里要注意,同步接口有网络延迟,建议加超时和重试。另外,ShowDoc 同步过程是"整体更新"还是"增量更新"取决于你转换器的实现,我这边是用"按目录重建"的方式,只更新自动生成目录下的页面,所以即使同步失败,ShowDoc 上还有上一次的旧数据,不至于页面全空。5.4 文档变化主动通知,不要等前端来问ShowDoc 本身不一定有很复杂的消息通知能力,但这不影响我们做变更通知。同步脚本执行成功后,可以在最后调用一个通知地址,把本次变更的接口清单发给协作群。我习惯在转换器里记录本次变更的路径和方法,拼成一段简短文本。这样前端不用天天刷新文档页面看有没有更新,后端在群里说一声"文档已同步,order 模块新增了下单接口",大家自然知道。通知逻辑不要放在同步接口内部,因为同步接口可能被多次触发;应该放在调用方(CI 的任务里),或者在同步接口返回结果后单独发一次通知。这个细节能避免前端收到重复打扰。6. 两年用下来,我遇到的坑和最终建议每个工具都有一套"看起来很美"的文档,但真正的价值藏在坑里。最后这部分全是我的真实经历。6.1 四个最容易让人崩溃的问题第一个坑是升级容器丢数据。我早期用 docker run 部署时没挂载目录,后来官方镜像升级,我直接把容器删了重建,结果所有文档全部清空。解决办法上面写过,挂载目录 + 定时备份,双保险。第二个坑是 API Key 泄露。某次代码审查发现同步脚本里的 token 被硬编码在配置文件中,而且配置文件不小心被提交到了仓库。虽然事后改了 token,但窗口期内知道 token 的人都能改文档,很难追责。现在所有密钥一律走环境变量,仓库里只放占位符。第三个坑是自动同步覆盖了手工补充。用了转换器后,脚本会把整个目录重建,手工维护的备注被冲掉过一次。后来我把自动生成的页面和手工维护页面放在不同目录,脚本只处理带"自动生成"标记的目录。第四个坑是文档"看起来全"但"没讲清"。打开页面,接口路径、参数类型都有,但没有示例值、没有枚举含义,前端依然要在群里问。这属于内容规范问题,不是工具问题,解决方法是把 4.2 节五个必填项作为 Code Review 的一部分,后端写完接口自己先打开 ShowDoc 看一眼再提交。6.2 和其他方案比,ShowDoc 的定位在哪里我不否定其他 API 文档工具,但每个工具的侧重点不同。拿我们常用的对比维度看:对比维度ShowDocSwagger UI 模式一体化调试管理平台部署成本较低,Docker 即可随应用部署较高,通常要引入中心化服务自动化程度靠 OpenAPI 转换 + 开放接口本身自动生成支持多渠道导入在线调试较弱,不擅长调试较好,直接试接口很强,集环境、断言、集合团队协作权限、目录、成员管理完善无权限概念偏平台化,适合较大团队私有化方便,适合内网随服务内网部署看版本,多需商业授权如果你们团队接口数量多到需要集合管理、调试、Mock、自动化测试,那一体化管理平台可能是更好的选择。但对大部分中小团队,ShowDoc 的轻量、私有化、配合 OpenAPI 自动同步已经能解决 80% 的问题。工具换得越频繁,团队对"文档必须更新"的敬畏感越低。6.3 我给正在入门的人三条建议第一条,先部署,再谈规范。把 ShowDoc 跑起来,手动维护两个接口试试手感,比空想一个月都有效。第二条,接入自动同步前,先把 Swagger 注解补完整,否则自动化推上去的也是垃圾内容。第三条,接受 ShowDoc 的不完美,它不是一个在线调试器,它是团队的知识库,你需要让它展示内容而不是承担所有接口工具的角色。我现在团队里的日常流程就是:Spring Boot 代码就是规范,SpringDoc 负责生成 OpenAPI JSON,转换器负责把 JSON 变成 ShowDoc 页面,CI 负责在发布后自动同步,前端在 ShowDoc 上看文档、在协作群里接收变更通知。如果你也准备把 ShowDoc 引入团队,别追求一步到位。先把服务跑起来,找两个真实接口维护出示例,然后让前端把 Word 扔掉,再慢慢加自动化。工具永远不是重点,重点是团队愿不愿意把接口信息当成代码的一部分去维护。
1. 先理解 ShowDoc 在 Spring Boot 开发里到底是什么角色做后端最烦的事情里,维护接口文档绝对能排进前五。我之前在某团队接手一个订单服务,代码里接口全有,但文档还停留在上一任同事离职前的 Word 版本,前端联调时对着旧文档问"这个参数明明没传啊",我一看代码,字段早改名了。就是从那时候开始,我把 Spring Boot API 接口文档的维护方式换成了 ShowDoc。这篇东西不是官方教程,是我从部署到落地,再到团队一起用起来的全过程记录,适合正在纠结"要不要上文档工具"的后端开发,也适合刚把 ShowDoc 装起来但不知道怎么接入 Spring Boot 的读者。1.1 ShowDoc 到底是个什么工具ShowDoc 从产品形态上说是一个私有化、可部署的在线文档系统。它最大的特点不是"生成接口文档",而是"什么文档都能往里放"。你可以新建一个接口项目,用 Markdown 或富文本维护每个接口的 URL、header、请求体、返回示例、错误码;也可以另开一个目录,把数据库字段字典、环境配置说明、部署手册全部整理进去。对 Spring Boot 项目来说,一个好的接口文档工具需要满足三个条件:第一,能承载自动生成的内容;第二,能支持团队在线编辑和评论;第三,能控制访问权限。ShowDoc 恰好三点都占。它不像 Swagger UI 那样只能展示 Swagger 注解生成的结果,也不像某些以调试为核心的工具那样只注重"能不能调通",它更像一个围绕接口资料的"内部 Wiki",接口信息只是其中一类页面。1.2 和 Word、Swagger UI 的真实对比我在实际项目里用过 Word、Swagger UI、ShowDoc 三种方式,体验差别很大。Word 文档的问题是完全没有强约束。谁改了代码不更新 Word,没人知道;多人同时编辑时版本互相覆盖;文档里写"详见 XX 文档"最后根本找不到。Swagger UI 的问题是"能看不能用"。它确实能根据注解实时生成接口列表,也能在线调试,但字段说明、业务含义、错误码意思、数据字典这些靠注解很难写清楚,而且一旦项目多了,Swagger UI 的导航会变得非常难用,还经常遇到跨域问题。ShowDoc 的价值在于把这几种工具的长处合到一起:接口列表从 OpenAPI 数据导入,字段说明、错误码、更新记录靠编辑页面补充,访问权限按项目划分,历史版本还能找回。我用下来最直观的感受是:前端拿到的不再是一堆 JSON schema,而是一份他们自己能看懂的"接口使用说明"。1.3 哪些项目适合选 ShowDoc不是所有团队都适合。如果是单机小 Demo,直接看 Swagger UI 就够;如果团队规模很大,已经在用一体化 API 管理平台,也没必要再引入 ShowDoc。ShowDoc 最合适的场景是:接口数量中等(几十到几百个)、前后端协作流程还没完全规范化、需要把接口文档放在公司内网、还需要有人能编辑权限的团队。我现在的团队就是用 Spring Boot 做微服务,每个服务一个工程,ShowDoc 按服务建项目,实践了半年,效果比之前好太多。2. 部署 ShowDoc 服务:我推荐私有化 Docker 方案ShowDoc 官方提供在线版,但介于接口文档通常带有业务信息,我不太建议把公司内部接口丢给第三方。私有化部署是最稳妥的选择,而 Docker 方案最省心。2.1 一条命令跑起来如果你服务器上已经装好 Docker,启动 ShowDoc 其实就是一句命令:docker run -d \ --name showdoc \ --restart=always \ -p 4999:80 \ -v /data/showdoc_data:/var/www/html/ \ showdoc/showdoc这条命令做了三件事:把容器命名为 showdoc,方便后续查看日志和启停;用--restart=always保证服务器重启后容器自动拉起;把宿主机的/data/showdoc_data目录挂载到容器 Web 根目录,这样文档数据不会随容器删除而丢失。启动完成后访问http://服务器IP:4999,走完初始化引导,用默认管理员账号登录并立即改掉密码。这里特别提醒,默认端口 80 被很多人挂在公网上扫到过,建议改成不常用端口,再配合防火墙只放行内网 IP 访问。2.2 数据备份恢复的完整做法ShowDoc 的数据存在 MySQL 和文件目录里,容器化部署后这些底层细节被隐藏了,我们只要保证挂载目录安全就行。我的备份策略很简单:每天凌晨压缩整个挂载目录,保留最近 7 天。tar -czf /backup/showdoc_$(date +%F).tar.gz -C /data showdoc_data find /backup -name "showdoc_*" -mtime +7 -exec rm -f {} \;恢复操作也直接:新服务器上把备份文件解压到同样的/data目录,再跑一遍 docker run 命令,数据就回来了。我踩过一次坑,是早期没意识到挂载目录的重要性,升级容器时直接删了容器,数据全丢。后来所有 docker run 都带上-v挂载,这个教训比任何配置都重要。2.3 项目和权限规划要提前做ShowDoc 安装好后第一件事不是写接口,而是规划项目结构。我建议按"服务域"建项目,比如用户服务、订单服务、商品服务,而不是把所有接口混到一个项目里。一个项目对应一个 ShowDoc 项目,权限好控制,文档也好维护。在 ShowDoc 后台,项目可以设置为私有项目,然后手动添加成员。角色我习惯只开两种:后端主程是编辑者,其他人是只读成员。前端同学一般不需要编辑权限,他们需要的只是稳定的只读地址。如果遇到要临时修改文档的情况,再提升权限,避免误操作污染文档。这一步看似简单,但对后面的自动化同步很关键,因为权限规划直接决定 API Key 的使用范围。3. Spring Boot 接入 ShowDoc:核心是把 Swagger JSON 变成同步任务ShowDoc 有一个很实用的能力:对外开放接口,允许你把外部系统生成的文档内容直接写入指定项目。这就给 Spring Boot 项目提供了一个自动化方案:用 SpringDoc 生成 OpenAPI JSON,再把 JSON 转成 ShowDoc 需要的页面结构,最后通过 ShowDoc 开放接口推送上去。3.1 为什么中间格式选 OpenAPI 而不是直接手写市面上很多人误以为"用 ShowDoc 就等于放弃 Swagger"。实际上两者是配合关系。Spring Boot 项目里通过注解维护接口信息,SpringDoc 会自动生成/v3/api-docs的 OpenAPI JSON。这个 JSON 是标准格式,包含接口路径、方法、参数、响应体和说明。ShowDoc 支持导入 OpenAPI 格式数据,也支持用开放接口创建页面。我之所以选择 OpenAPI 作为中间层,是因为它"两边不吃亏":开发时用注解,IDE 能检查;文档更新时由脚本把 JSON 转换推送,不用人去一个个复制参数。如果哪一天团队决定换文档工具,OpenAPI JSON 还能继续导入别的平台,数据不会被绑死。3.2 Spring Boot 侧配置 SpringDoc在 Spring Boot 工程里加入 springdoc-openapi 依赖后,它自动扫描 Controller 上的注解。下面是基础配置:springdoc: api-docs: enabled: true path: /v3/api-docs swagger-ui: path: /swagger-ui.html启动项目后访问http://localhost:8080/v3/api-docs,能看到一个很大的 JSON,这就是 OpenAPI 数据。为了让这个 JSON 内容够完整,Controller 类和方法上的注解要写全,稍后我会在第四节专门讲字段规范。这里先记住一个原则:注解里写清楚的内容,会原样进入 ShowDoc,注解里没有的内容,后面就得靠手工补,工作量大得多。3.3 同步服务的核心代码ShowDoc 的开放接口逻辑是:准备好 API Key、API Token、项目 ID,然后把文档内容 POST 上去。不同部署地址的开放接口路径可能不一样,去后台的"开放 API"页面能看到当前地址对应的示例。我封装的同步服务简化后是这样:@Service public class ShowDocSyncService { private final RestTemplate restTemplate = new RestTemplate(); @Value("${showdoc.api-url}") private String apiUrl; @Value("${showdoc.api-key}") private String apiKey; @Value("${showdoc.api-token}") private String apiToken; @Value("${showdoc.item-id}") private String itemId; public void syncFromSwagger(String swaggerJson) { // 这里把 OpenAPI JSON 转换成 ShowDoc 的目录和页面结构 // 推荐的做法是遍历 paths 节点: // 每个 tag 作为一个目录,每个 path+method 作为一个页面 List<Map<String, Object>> catalogs = Converter.toShowDocPages(swaggerJson); MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("api_key", apiKey); params.add("api_token", apiToken); params.add("item_id", itemId); params.add("data", JacksonUtils.toJson(catalogs)); ResponseEntity<String> response = restTemplate.postForEntity(apiUrl, params, String.class); // 判断 response body 中的状态,失败则抛出异常 } }这个类的重点在Converter.toShowDocPages,它负责把 Swagger JSON 里的paths和tags映射成 ShowDoc 页面层级。比如一个"用户管理" tag 下有三个接口,最终在 ShowDoc 里就是一个"用户管理"目录,下面挂着三个接口页面。转换逻辑不难,但要注意几个问题。第一,OpenAPI 里同一个 path 可能对应多个 HTTP 方法,比如/user/{id}有 GET 和 PUT,页面标题要带上[GET]前缀,否则同名页面会互相覆盖。第二,ShowDoc 的页面内容是 Markdown,转换时要把请求体、响应体、参数表转成 Markdown 表格,才能保证前端阅读体验。第三,不要把所有接口塞到一个页面,按接口页面拆分,方便单独维护。3.4 触发方式:手动按钮 + CI 自动同步同步代码写好后,触发方式我推荐两个层面。开发阶段,写一个 Spring Boot 单元测试或一个ApplicationRunner,启动时打一个开关,需要时手动调用 sync 方法。发布阶段,在 CI 构建脚本里加一段请求,让测试通过后自动执行同步。# 假设同步服务本身也暴露了一个受保护的 HTTP 接口 /sync/api-docs curl -X POST http://localhost:8080/sync/api-docs \ -H "Content-Type: application/json" \ -d '{"secret":"your-sync-token"}'这里有一个特别容易踩的坑:同步接口不要不加保护地暴露到公网。用 ShowDoc 开放接口时,API Token 本身是一个高权限凭据,任何拿到它的人都能直接修改文档。所以代码仓库里绝对不能提交真实 token,要用环境变量注入,同步接口也要加一层自己的签名。4. 让文档真正好用:接口内容规范比工具选型更重要我见过不少团队,工具从 Word 换到 ShowDoc,文档还是一团糟。原因很简单,工具解决的是"放哪",不解决"写什么"。Spring Boot 接口文档要让人愿意看,核心是把字段、返回值、错误码这三件事说清楚。4.1 统一返回结构,文档里只放一个真实示例很多 Spring Boot 项目用Result<T>包一层,这没问题,但接口文档里最常见的错误是:所有接口的返回示例都写成{code:0, message:"成功", data:{}},data 里面到底长什么样完全没说。前端拿到这种文档还是得来问你。我的习惯是,在 Controller 的注解里直接用具体响应对象,让生成的 OpenAPI JSON 里能看到 data 的结构。比如:@Operation(summary = "查询订单详情") @GetMapping("/order/{id}") public Result<OrderDetailVO> getOrder(@PathVariable Long id) { return Result.success(orderService.getDetail(id)); }然后在OrderDetailVO的每个字段上写@Schema(description = "订单状态:0-待支付,1-已支付,2-已取消")。这样 Swagger JSON 里的字段说明完整,同步到 ShowDoc 后前端就能直接看到 data 结构,而不是一个空的{}。4.2 字段说明的五个必填项写字段说明时,我要求团队每个字段至少回答五个问题:字段名是什么;类型是什么(string / integer / boolean / object / array);是否必传;取值范围或枚举含义;一个真实可用的示例值。举个例子,订单状态如果只写"状态"两个字,前端大概率搞不清楚;如果写成"订单状态,可选值:1待支付、2已支付、3已取消,示例:2",联调效率会高很多。这些内容都可以直接写在@Schema注解里。需要注意,注解里的example属性会进入 OpenAPI JSON,ShowDoc 转换后也可以保留,所以示例值一定要填,别嫌麻烦。4.3 错误码单独维护一个页面HTTP 状态码和业务错误码是两码事。很多接口返回 HTTP 200,但业务 code 是 10001 表示"订单不存在"。如果文档里不把业务错误码列清楚,前端同事只能靠猜。我在 ShowDoc 项目里固定建一个"错误码说明"目录,用 Markdown 表格维护所有业务 code、含义、建议处理方式。这个目录用脚本自动同步时不要覆盖,保留给人工维护。错误码的规范要用排除法:所有接口共用一个 code 字段,不要某个接口返回success、另一个接口返回status,这种不一致是文档大忌。4.4 目录结构要有头脑,不要全部堆在顶层ShowDoc 的项目页面是按目录组织的。目录建议按"业务模块"而不是"Controller 类"来建。比如订单服务下面分"订单查询""订单操作""售后流程",这样前端按业务场景找接口,比按类名一个一个翻要快。另外,我会给每个模块目录配一个"使用说明"页面,写清楚这个模块的业务背景、通用 header、必填 token、分页规则。这类页面用自动化脚本创建一次就不动了,后续手工补充。把"自动同步生成的页面"和"手工维护的页面"分开,是防止脚本覆盖人工内容的最后一道防线。5. 团队协作中真正提升效率的四个习惯ShowDoc 安装后如果只是一个人上传文档,那它只是一个网盘。要让它发挥价值,必须把它嵌进团队的工作流里。5.1 访问权限要分清,API Key 也要分级别给前端同学分配只读账号,而不是把项目链接直接扔到群里让大家匿名访问,这是我对团队的最低要求。只读账号的好处是可追溯、可撤销,新人进来给他开账号,有人离职直接禁用,不用换整个项目链接。对自动化同步用的 API Key 也要单独建一个"机器人"账号,不要拿管理员的 Key 去写脚本。这样就算脚本里的 Key 泄露,权限只影响指定项目,不会波及整个 ShowDoc 服务。这个问题容易被忽视,我见过有团队把管理员 token 直接写在前端代码里,最后整个文档库都被人清空了。5.2 Mock 数据与并行开发后端接口还没写完时,前端最痛苦的是没有数据可以联调。ShowDoc 的页面内容本身就是 Markdown,可以在里面维护一份完整的返回示例,前端照着示例写死数据先开发页面。等后端好了再切换真实接口,大部分逻辑不用改。这个方法比单独搭 Mock 服务更轻量。我在实践中的体会是,Mock 服务适合接口数量大、团队已经有一套流程的场景;而 ShowDoc 加"约定返回示例"的方式,适合中小团队让前后端先对齐数据结构。关键点在于,返回示例必须写的是"真实数据结构",不能为了示例好看而编一个和实际代码不一致的字段。否则前端按示例写的数据结构到了联调阶段全部要返工,比没有 Mock 更糟。5.3 把文档更新动作放进发布流程最容易老化的文档就是"没人主动去更新"的文档。我现在要求:只要后端接口有变更,代码合并之前必须把同步脚本跑一遍。这样才能保证线上文档和代码是同一版本。你在 CI 里加一个步骤,构建成功后调用同步接口,发布没成功文档就不会更新,这个联动帮团队省了很多心。CI 脚本里要注意,同步接口有网络延迟,建议加超时和重试。另外,ShowDoc 同步过程是"整体更新"还是"增量更新"取决于你转换器的实现,我这边是用"按目录重建"的方式,只更新自动生成目录下的页面,所以即使同步失败,ShowDoc 上还有上一次的旧数据,不至于页面全空。5.4 文档变化主动通知,不要等前端来问ShowDoc 本身不一定有很复杂的消息通知能力,但这不影响我们做变更通知。同步脚本执行成功后,可以在最后调用一个通知地址,把本次变更的接口清单发给协作群。我习惯在转换器里记录本次变更的路径和方法,拼成一段简短文本。这样前端不用天天刷新文档页面看有没有更新,后端在群里说一声"文档已同步,order 模块新增了下单接口",大家自然知道。通知逻辑不要放在同步接口内部,因为同步接口可能被多次触发;应该放在调用方(CI 的任务里),或者在同步接口返回结果后单独发一次通知。这个细节能避免前端收到重复打扰。6. 两年用下来,我遇到的坑和最终建议每个工具都有一套"看起来很美"的文档,但真正的价值藏在坑里。最后这部分全是我的真实经历。6.1 四个最容易让人崩溃的问题第一个坑是升级容器丢数据。我早期用 docker run 部署时没挂载目录,后来官方镜像升级,我直接把容器删了重建,结果所有文档全部清空。解决办法上面写过,挂载目录 + 定时备份,双保险。第二个坑是 API Key 泄露。某次代码审查发现同步脚本里的 token 被硬编码在配置文件中,而且配置文件不小心被提交到了仓库。虽然事后改了 token,但窗口期内知道 token 的人都能改文档,很难追责。现在所有密钥一律走环境变量,仓库里只放占位符。第三个坑是自动同步覆盖了手工补充。用了转换器后,脚本会把整个目录重建,手工维护的备注被冲掉过一次。后来我把自动生成的页面和手工维护页面放在不同目录,脚本只处理带"自动生成"标记的目录。第四个坑是文档"看起来全"但"没讲清"。打开页面,接口路径、参数类型都有,但没有示例值、没有枚举含义,前端依然要在群里问。这属于内容规范问题,不是工具问题,解决方法是把 4.2 节五个必填项作为 Code Review 的一部分,后端写完接口自己先打开 ShowDoc 看一眼再提交。6.2 和其他方案比,ShowDoc 的定位在哪里我不否定其他 API 文档工具,但每个工具的侧重点不同。拿我们常用的对比维度看:对比维度ShowDocSwagger UI 模式一体化调试管理平台部署成本较低,Docker 即可随应用部署较高,通常要引入中心化服务自动化程度靠 OpenAPI 转换 + 开放接口本身自动生成支持多渠道导入在线调试较弱,不擅长调试较好,直接试接口很强,集环境、断言、集合团队协作权限、目录、成员管理完善无权限概念偏平台化,适合较大团队私有化方便,适合内网随服务内网部署看版本,多需商业授权如果你们团队接口数量多到需要集合管理、调试、Mock、自动化测试,那一体化管理平台可能是更好的选择。但对大部分中小团队,ShowDoc 的轻量、私有化、配合 OpenAPI 自动同步已经能解决 80% 的问题。工具换得越频繁,团队对"文档必须更新"的敬畏感越低。6.3 我给正在入门的人三条建议第一条,先部署,再谈规范。把 ShowDoc 跑起来,手动维护两个接口试试手感,比空想一个月都有效。第二条,接入自动同步前,先把 Swagger 注解补完整,否则自动化推上去的也是垃圾内容。第三条,接受 ShowDoc 的不完美,它不是一个在线调试器,它是团队的知识库,你需要让它展示内容而不是承担所有接口工具的角色。我现在团队里的日常流程就是:Spring Boot 代码就是规范,SpringDoc 负责生成 OpenAPI JSON,转换器负责把 JSON 变成 ShowDoc 页面,CI 负责在发布后自动同步,前端在 ShowDoc 上看文档、在协作群里接收变更通知。如果你也准备把 ShowDoc 引入团队,别追求一步到位。先把服务跑起来,找两个真实接口维护出示例,然后让前端把 Word 扔掉,再慢慢加自动化。工具永远不是重点,重点是团队愿不愿意把接口信息当成代码的一部分去维护。