Kratos 必须通过 protoc-gen-openapiv2 插件从 .proto 文件生成 OpenAPI v3 文档,因 API 源头为 Protobuf 且依赖 google.api.http 扩展;swag 注释方式无效,无法识别 proto 语义,易导致字段名错乱、路径丢失等问题。

Kratos 本身不内置 Swagger 文档生成能力,必须靠 protoc 插件从 .proto 文件中提取 OpenAPI v3 定义——这是唯一可靠、与 Kratos 架构对齐的路径。手动写 YAML 或用注释生成(如 Gin 的 swag init)在 Kratos 里不适用,也不推荐。
为什么不能用 swag 注释方式生成文档
Kratos 的 API 定义源头是 Protobuf,HTTP 路由、参数、响应结构全部由 google.api.http 扩展和 protoc-gen-go-grpc 等插件从 .proto 自动生成。你写在 Go 文件里的 // @Summary 这类注释不会被 Kratos 工具链识别,swag 命令也根本读不到 proto 中的语义信息。
常见错误现象:
- 运行
swag init后docs/目录为空或报错no @title found - 即使生成了
swagger.json,字段名、路径、参数类型全错(比如把user_id显示成userId,或漏掉body参数) - gRPC-to-REST 映射的 HTTP 方法(
POST /v1/users)、请求体嵌套结构完全丢失
正确做法:用 protoc-gen-openapiv2 生成 swagger.json
必须使用官方支持的 protoc 插件,它能准确解析 google.api.http 和 validate.proto 规则,并输出符合 OpenAPI v3 标准的 JSON。
实操步骤:
- 安装插件:
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest - 确保
protoc可执行文件在$PATH中(可用protoc --version验证) - 在项目根目录执行(注意替换真实 proto 路径):
protoc \ --proto_path=. \ --proto_path=./third_party \ --openapiv2_out . \ --openapiv2_opt logtostderr=true \ --openapiv2_opt json_names_for_fields=false \ api/helloworld/v1/greeter.proto
- 生成的
greeter.swagger.json会落在同级目录,可直接用于 Swagger UI 加载
关键参数说明:
-
--openapiv2_opt json_names_for_fields=false:禁用字段名自动转 camelCase,保持 proto 中定义的snake_case(如user_id),否则前端调用时容易出错 -
--proto_path=./third_party必须包含,否则无法解析google/api/annotations.proto和validate/validate.proto
如何让 Swagger UI 在 Kratos 服务中可访问
Kratos 默认不提供静态资源托管能力,需自行注册路由并嵌入 HTML + JS 资源。最轻量的做法是用 //go:embed 将 Swagger UI 资源和生成的 swagger.json 一起打包进二进制。
操作要点:
- 将生成的
greeter.swagger.json放到api/swagger/目录下 - 下载 Swagger UI 静态文件(如从 Swagger UI Releases 下载
dist/内容),放入api/swagger/ui/ - 在
cmd/server/main.go中添加嵌入声明:import _ "embed" <p>//go:embed swagger/ui/* var swaggerUI embed.FS</p><p>//go:embed swagger/*.json var swaggerJSON embed.FS
- 注册 HTTP 路由时挂载:
r := gin.New() r.StaticFS("/swagger", http.FS(swaggerUI)) r.GET("/swagger/doc.json", func(c *gin.Context) { data, _ := swaggerJSON.ReadFile("swagger/greeter.swagger.json") c.Data(200, "application/json", data) })
访问 http://localhost:8000/swagger/ 即可看到交互式文档,且所有接口均来自 proto 定义,与实际服务完全一致。
最容易被忽略的是 json_names_for_fields=false 这个开关——不加它,Swagger UI 里显示的请求体字段名和你 proto 里写的不一致,前端同学会以为后端改了字段,其实只是插件默认做了转换。这个细节一旦漏掉,调试成本会陡增。


















