应选swag CLI,因go-swagger已停止维护且泛型支持差;swag轻量活跃、兼容性强,需用go install github.com/swaggo/swag/cmd/swag@latest安装,并在项目根目录执行swag init -g cmd/main.go -o docs/。

Swagger文档自动生成:用swag CLI还是go-swagger?
Go项目里想自动从代码生成Swagger(OpenAPI 3.0)文档,swag 是当前最轻量、维护活跃、且与Go标准库和常见Web框架(如gin、echo、net/http)兼容性最好的选择。go-swagger 已停止维护,且对Go泛型支持差,生成的结构体定义常漏字段或嵌套错误。
实操建议:
- 安装最新版
swag:go install github.com/swaggo/swag/cmd/swag@latest(注意不是swaggo/swag,旧路径已失效) - 必须在项目根目录(含
main.go或入口包)执行swag init -g cmd/main.go -o docs/,否则扫描不到 handler 和 model -
swag init不会递归扫描 vendor 或外部模块,所有// @success引用的 struct 必须定义在本项目内,或通过// @model显式声明别名
API注释怎么写才被swag识别?关键三要素缺一不可
swag 只认特定格式的 Go 注释块(以 // @ 开头),且必须紧贴 handler 函数上方——中间不能插空行或其它注释。漏掉任意一个核心指令,对应接口就不会出现在生成的 swagger.json 中。
典型写法示例(以 gin handler 为例):
立即学习“go语言免费学习笔记(深入)”;
// @Summary 获取用户列表
// @Description 分页查询用户,支持按昵称模糊匹配
// @Tags users
// @Accept json
// @Produce json
// @Param page query int true "页码,从1开始"
// @Param limit query int false "每页数量,默认20" default(20)
// @Success 200 {array} models.UserResponse "用户列表"
// @Failure 400 {object} models.ErrorResponse "参数校验失败"
// @Router /api/v1/users [get]
func GetUsers(c *gin.Context) { ... }
容易踩的坑:
-
@Success和@Failure的返回类型必须是完整可解析的 Go 类型路径,比如models.UserResponse,不能写*UserResponse或[]User(swag 不支持指针/切片语法缩写) -
@Param的query/path/header类型必须与实际绑定方式一致;用ShouldBindQuery却写成@Param xxx path string,会导致文档错乱 -
@Router路径末尾不要加/,否则生成的 URL 多一层斜杠,前端调用 404
中文文档支持:不改源码也能让Swagger UI显示中文
swag 默认生成的 JSON 里所有 description、summary 都是原始注释内容,但 Swagger UI 渲染时若页面编码或字体缺失,中文可能显示为方框或乱码。这不是 swag 的问题,而是前端静态资源加载配置问题。
解决方法很简单:
- 确保
docs/swagger.json文件本身是 UTF-8 编码(VS Code / GoLand 默认就是,但用 vim 或某些 CI 工具生成时可能被转成 GBK) - 在 Web 服务中提供
/swagger/*any路由时,显式设置响应头:c.Header("Content-Type", "application/json; charset=utf-8") - 如果用
swag.Handler(如 gin-swagger),它内部已设好 charset,但需确认你没在中间件里覆盖了Content-Type
不需要修改 swag 源码,也不用额外引入 i18n 包——只要注释本身是 UTF-8,且传输过程没被转码,中文就能正常显示。
语言学习类API的特殊规范:如何表达多语言字段与状态码语义
语言学习 API 常涉及多语言文本(如单词释义、例句)、用户学习进度状态、难度等级等,这类字段不能简单用 string 或 int 描述,否则文档无法体现业务约束。
推荐做法:
- 用
// @Schema为枚举字段加说明,例如:// @Schema enum="beginner,intermediate,advanced"放在 struct 字段注释上 - 多语言字段统一用 map[string]string 表示,如
Translations map[string]string `json:"translations"`,并在@Success中注明:// @Success 200 {object} map[string]string "key为语言代码(zh/en/ja),value为对应翻译" - 避免把 HTTP 状态码当业务逻辑用:比如“单词已掌握”返回
204 No Content,而“单词不存在”返回404—— 这会让前端难以区分是网络错误还是业务拒绝,应统一用200+ 明确的status字段
最易被忽略的一点:语言代码必须用 IETF BCP 47 标准(如 zh-CN、en-US),而不是随意写 ch 或 english;文档里不声明,前端就只能靠猜,后期联调成本陡增。


















