grpc-gateway 怎么把多个 proto 文件的 OpenAPI 输出合并为单个 swagger 文件【免费下载链接】grpc-gatewaygRPC to JSON proxy generator following the gRPC HTTP spec项目地址: https://gitcode.com/GitHub_Trending/gr/grpc-gateway如果你的 protobuf 定义分散在多个.proto文件里grpc-gateway 的 OpenAPI 插件默认会为每个输入文件各生成一个输出文件protoc-gen-openapiv2为每个.proto生成一个*.swagger.jsonprotoc-gen-openapiv3为每个.proto生成一个*.openapi.json。问题在于OpenAPI 的规范本身把一次 API 描述为一个文档把规格拆散到多个文件会改变 schema 结构也直接喂给很多 OpenAPI 消费者UI 查看器、客户端生成器、网关配置。针对这个多个 proto → 单个 OpenAPI 文档的任务仓库里有两条官方路径使用protoc-gen-openapiv2输出 Swagger 2.0 / OpenAPI 2.x生成foo.swagger.json给插件加allow_merge和merge_file_name两个选项在一次生成中直接输出单个合并文件。使用protoc-gen-openapiv3输出 OpenAPI 3.1.0 JSON先生成每个文件一份的输出再用配套的openapiv3-merge工具把多份 JSON 合并成一个文档。两条路径都只作用于生成的 OpenAPI 规格文件不改变 gateway 运行时的行为。下面分别给出完整操作步骤。路径一protoc-gen-openapiv2 用 allow_merge 直接合并这是生成单个swagger.json的最短路径合并发生在插件内部不需要后处理脚本。方式 Aprotoc 命令行在protoc调用上追加--openapiv2_opt allow_mergetrue,merge_file_namefooprotoc -I. \ --openapiv2_out. \ --openapiv2_opt allow_mergetrue,merge_file_namefoo \ path/to/a.proto path/to/b.protomerge_file_name是合并后目标文件的文件名前缀foo会产出单个foo.swagger.json而不是按 proto 文件数量散落的多个*.swagger.json。两个选项在 protoc-gen-openapiv2/main.go 中的定义也确认了这一点allow_merge为if set, generation one OpenAPI file out of multiple protosmerge_file_name为target OpenAPI file name prefix after merge。方式 Bbuf 配置如果生成流程走buf.gen.yaml把选项放进 plugin 的opt- name: openapiv2 out: foo opt: allow_mergetrue,merge_file_namefoo文档特别提示合并文件较多时可能需要把 generation strategy 设为all- name: openapiv2 out: foo strategy: all opt: allow_mergetrue,merge_file_namefoo合并后路径顺序默认情况下生成的 Swagger 文件中 paths 按字母序排列。如果你希望合并后路径顺序跟随 proto 文件的书写顺序加上preserve_rpc_ordertrue选项即可。文档明确说明该选项覆盖合并场景When merging protobuf files, paths will preserve their ordering depending on the order of files specified on the command line.protoc --openapiv2_out. --openapiv2_optpreserve_rpc_ordertrue ./path/to/file.proto或 bufversion: v1 plugins: - name: openapiv2 out: . opt: - preserve_rpc_ordertrue路径二protoc-gen-openapiv3 用 openapiv3-merge 后处理合并如果你需要的是 OpenAPI 3.1 输出protoc-gen-openapiv3刻意遵循1 个输入文件 → 1 个输出文件的 protobuf 惯例因此合并是独立的第二步安装并运行 openapiv3-merge 工具。注意protoc-gen-openapiv3目前是 Alpha 状态输出 JSON 形状可能在 minor 版本之间变化文档同时说明它不消费grpc.gateway.protoc_gen_openapiv2.options注解集不产出 Swagger 2.0/YAML。如果你依赖 v2 注解或需要生产稳定的 OpenAPI 管线应留在路径一。安装go install github.com/grpc-ecosystem/grpc-gateway/v2/openapiv3-mergelatest生成每文件的 OpenAPI 文档以 protoc 为例buf 则是照常buf generate在每个声明了 HTTP 绑定的 proto 旁出现一份.openapi.json#!/usr/bin/env bash set -euo pipefail protoc -I. \ --openapiv3_out./gen \ $(find . -name *.proto) rootgen/api/v1/api.openapi.json mapfile -t rest (find gen -name *.openapi.json ! -path $root | sort) openapiv3-merge $root ${rest[]} gen/api.openapi.json脚本里root指向上面这条命令会生成哪份文档请按你的 proto 目录结构替换为实际路径find收集的其余*.openapi.json按字典序排列保证结果确定。输入顺序很重要合并文档的info、servers、externalDocs取自第一个输入后面输入的这些字段会被丢弃。所以要把范围最宽、承载共享openapiv3_document注解title/version/servers 等的那份文件放最前。如果没有任何文件被指定为根文档的建议是全部按字典序排序、接受排序靠前的那份——但要在对应 proto 上设置openapiv3_document注解合并结果的title、version、servers才有合理的值。对于任意输入都能排第一的简单目录也有 one-shot 写法openapiv3-merge $(find . -name *.openapi.json | sort) api.openapi.json结果验证合并文档写到 stdout示例中重定向为gen/api.openapi.json错误写到 stderr进程以非零状态退出。产出的 spec 可验证为 OpenAPI 3.1.0能直接喂给任意 3.1 兼容工具文档给出的示例是openapi-generator-cli做客户端生成。输出字段顺序遵循 OpenAPI 3.1.0 声明顺序openapi、info、servers、paths、webhooks、components、security、tags、externalDocs再跟扩展字段paths/webhooks按输入顺序输出components/*子图按 key 排序。openapiv3-merge 的合并规则与冲突排查合并器是严格模式任何可能被静默覆盖的地方都会报错。字段级规则如下来自 docs/docs/mapping/openapi_v3_merge.md字段规则openapi所有输入必须一致info、servers、externalDocs取第一个输入后续输入的值被丢弃paths、webhooks按输入顺序并集同一路径内容不一致 → 报错components/*并集key 排序输出同名内容不一致 → 报错tags按name去重同名但元数据不一致 → 报错security第一个声明非空数组的输入胜出后续声明不同非空数组 → 报错未知顶层键x-*扩展取第一个输入内容不一致是按规范化比较判定的仅 key 顺序不同的两个值视为相等。由于protoc-gen-openapiv3用完全限定 proto 名如example.v1.User命名 component schema跨包复用同一 message 时每个输出贡献的是同一个、内容一致的 component合并可以干净通过。合并失败时错误信息会指出冲突字段文档给出的示例openapiv3-merge: paths./v1/echo: echo.openapi.json redefines an entry with a different value文档列出的常见原因路径定义冲突两个 proto 声明了相同 HTTP 路径但绑定不同需要确定哪份是权威定义。component 定义冲突同名同包的全限定 message 名但形状不同——通常意味着 proto 树里存在重复的package message 声明。tag 元数据冲突两份openapiv3_document.tags注解对同名 tag 给出了不同描述需统一或把元数据收敛到一处。OpenAPI 版本不匹配所有输入必须声明相同的openapi值。两条路径怎么选你生成的是 Swagger 2.0*.swagger.json或依赖openapiv2_schema/openapiv2_operation等 v2 注解用allow_mergetrue,merge_file_name...一次生成即得到单文件。你生成的是 OpenAPI 3.1*.openapi.jsonv3 插件没有内置合并选项必须用openapiv3-merge做后处理同时注意它是 Alpha且不支持 YAML 输出。两条路径都只做文档层面的合并不影响 gateway 的 HTTP 行为本身。参考文档Customizing OpenAPI Output — Merging outputallow_merge、merge_file_name、preserve_rpc_order的说明。Merging OpenAPI 3.1 Outputopenapiv3-merge的安装、用法与合并规则。OpenAPI 3.1 Outputprotoc-gen-openapiv3的 Alpha 状态、能力边界与选项。openapiv3-merge README 与 merge 实现字段级规则与严格模式的源码依据。【免费下载链接】grpc-gatewaygRPC to JSON proxy generator following the gRPC HTTP spec项目地址: https://gitcode.com/GitHub_Trending/gr/grpc-gateway创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考