本文档主要描述在 gin 框架下用 gin-swagger 生成 swagger.json 的内容,中间猜的坑。以及,如何把 swagger 2.0 转成 openapi 3.0.3
下面操作均在项目根目录下执行
生成 swagger 2.0
import swagger
go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files
main.go 或者 main 函数所在代码内 import 上面 go get 的包
import "github.com/swaggo/gin-swagger" // gin-swagger middleware
import "github.com/swaggo/files" // swagger embed files
通用 API 注释
在 main.go 或者 main 函数所在代码内添加
具体可以添加的注释见:https://github.com/swaggo/swag?tab=readme-ov-file#general-api-info
// @title Swagger Example API
// @version 1.0
// @description This is a sample server celler server.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8080
// @BasePath /api/v1
给 controller 接口加注释
具体可以添加的注释见:https://github.com/swaggo/swag?tab=readme-ov-file#api-operation
// Ksd 人声分离接口
// @Summary 人声分割
// @Description 传入语音来做人声分割
// @Tags ksd
// @Accept mpfd
// @Produce json
// @Param json body KsdReq true "KsdReq"
// @Response 200 {object} CommonResp{data=KsdResp}
// @Router /aihc/v1/speaker/ksd [post]
func Ksd(ctx *gin.Context) {}
KsdReq 和 CommonResp 是自己定义的 struct,可以直接引用
如果是嵌套的,比如我的 CommonResp 是:
type CommonResp struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
那对应接口返回值就可以用 CommResp{data=KsdResp} 来赋值,出来的网页就会带上这个 KsdResp
构建 swagger docs
在执行 swag 前先 install
go install github.com/swaggo/swag/cmd/swag@latest
再调用下面指令生成 docs 目录
swag init
问题
-
如果 main 函数所在文件不叫 mian.go
比如我的 main 函数在 speaker-svc.go
swag init -g speaker-svc.go
-
Error parsing type definition
如果出现这个,可能是你确实类型写错了,另一个就是缺少下面两个参数。就是要解析目录中的 go 源文件,以及解析 internal 包中的 go 文件。
swag init --parseDependency --parseInternal
-
swagger ‘LeftDelim’ unknow
更新 swag 包
go get -u github.com/swaggo/swag
最后指令,我用的是
swag init -g speaker-svc.go --parseDependency --parseInternal
导入 docs 目录
如果不加打开页面会出现:Fetch error Internal Server Error doc.json
在 main.go 或者 main 函数的代码内导入生成的 docs。path 是你项目的根目录,或者你放到 pkg 下面或者哪里。
import "/path/docs"
路由添加 swagger
r 是 gin.New()
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
验证
http://localhost:8080/swagger/index.html
转换 openapi 3.0.1
方法1:swagger converter
要转换成 3.0.0 是因为最近在尝试,把接口导入 LLMOps 的插件里面,都需要 openapi 的 spec,所以就想说找一下。找了很多方式,最快捷的还是用官方自带的 swag convertor。调用里面的接口,或者用页面的测试,都可以。输入就是上面生成的 swagger.json,输出就是 openapi 的 spec,很明显的标志就是第一行会是 "openapi": "3.0.1"
,之前是 "swagger": "2.0"
https://converter.swagger.io/#/
这个网站可以私有化部署,所以可以部署到本地去,方法见:https://github.com/swagger-api/swagger-converter
方法2:封装转换代码
查看了 go-openapi 官方代码和 kin-openapi 做了整合,通过对生成的 swagger.json 做转换
代码见:swagger2openapi3
后面为了方便,打算把 swag 那个工具改一下,把输出的 swagger.json 直接调这个接口,然后生成,省的每次都贴来贴去。
如果有更好的方法或者其他错误,欢迎讨论。