好久没有给别人写接口了,正好遇到一个前后端合作的项目,是时候尝试一下 golang swagger 的 API 文档生成工具了。
注意:尝试了 swaggo 之后,感觉很不好(注释规范口味太重,与三方库有冲突),我觉得再试试 go-swagger。但是没想到 go-swagger 更难上手,且生成速度巨慢,无法接受,还是继续使用 swaggo。
使用 swagger 的好处
- 返回的数据结构,可以直接引用 struct 的定义:https://github.com/swaggo/swag , 但是同时带来了问题,如果 struct 里嵌入了三方库的类型,依赖检测时会出现与 swaggo 规范冲突的注释。
- 如果自己只是写后台,用 swagger 的 ui 界面可以方便的自测。避免了交付给同事有 bug 的接口
安装 swag 工具
go install github.com/swaggo/swag/cmd/swag@latest
创建 docs.go 并生成文档
修改默认文件目录。默认 swagger 会使用 docs 目录。 但是 docs 目录已经被我用了,想换个目录作为 swagger 生成文件的目录。 可以使用 output 指定输出目录。
> swag init --output api_docs --exclude frontend
2022/08/24 13:04:29 Generate swagger docs....
2022/08/24 13:04:29 Generate general API Info, search dir:./
2022/08/24 13:04:31 create docs.go at api_docs/docs.go
2022/08/24 13:04:31 create swagger.json at api_docs/swagger.json
2022/08/24 13:04:31 create swagger.yaml at api_docs/swagger.yaml
查看生成了哪些文件
> ls api_docs/
docs.go swagger.json swagger.yaml
在没有 swagger 格式的注释时,似乎也没有生成啥有用的文档。
注意,每次修改了文档,都需要执行 swag init 命令。
跑起来
参照:
https://github.com/swaggo/gin-swagger
go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files
修改 main.go,并编译。
浏览器访问:
http://localhost:8000/swagger/index.html
即可看到 API 文档。
编译后的文件大小变化
- 使用前是 21M。
- 使用后是 33M。
发布方式
swaggo 是直接 build 到二进制里的,会极大增加二进制文件的大小(参考上面的数据 21M 到 33M),一般在生产环境不需要将 docs 编译进去。
可以利用 go 提供的条件编译来实现是否编译文档。
不适合打包到 API 服务里。
安全起见,用完后,将服务关掉。
使用 jwt token 的 API
https://github.com/swaggo/gin-swagger/issues/90
疑虑
swagger 文档会不会让代码注释过于复杂。特别是让人不适的 at 符号,感觉进入了 java 的世界。跟 golang 的小清新风格不符
params 类型:body 还是 formData
https://stackoverflow.com/questions/23118249/whats-the-difference-between-request-payload-vs-form-data-as-seen-in-chrome
body 实际上是 payload body,如果提交的是序列化后的 json 字符串,就是 body.
cannot find type definition: gorm.Model
https://github.com/swaggo/swag/issues/810
swag init --parseDependency --parseInternal
但是加个这两个参数之后,又会引出更多的三方库报错,例如:
missing required param comment parameters
原因是,三方库也用了跟 swagger 同名的注解前缀,但是格式不同,就报错了。 这点让我无法接受,我觉得尝试一下 go-swagger 来替代 swaggo。
还会有更奇葩的错误:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x85c8a8]
最好是不要在注释里关联使用了三方库的 struct,例如 gorm。struct 字段可以用纯文本描述。可以用 any 类型代替。
TODO
- antd pro API VIM Snippet 更新成 swagger 格式
- 直接开搞,先生成 docs 看看格式。是否可以直接用 nginx 发布。
- Makefile
参考
- 注释规范参考 https://github.com/swaggo/swag
- 代码参考 https://github.com/swaggo/gin-swagger
- https://www.lixueduan.com/posts/go/swagger/
tags: swagger