swaggo/swag 通过解析 Go 源码注释自动生成 OpenAPI 文档,需严格遵循注释语法(如 @Summary、@Success、@Router),结构体加 swagger:model 标签,参数显式声明,配合 gin-swagger 可嵌入交互式 UI;CI/CD 中须强制校验 docs/swagger.json 一致性以防文档滞后。
Go 项目里手写 OpenAPI(Swagger)文档既易出错又难维护,swaggo/swag 是目前最主流的方案:它通过解析源码中的注释,直接生成 swagger.json,零运行时开销,且与 Gin/Echo/Chi 等框架天然兼容。
关键前提是:注释必须严格遵循特定语法,否则 swag init 会静默跳过或报错。
// @Summary、// @Success、// @Router 三类基础注释// swagger:xxx 标签(如 // swagger:model)才能被识别为 schema/users/{id})时,// @Param id path int true "user ID" 必须显式声明swag init 默认只扫描当前目录及子目录,跨模块需用 -g 指定入口文件,用 -o 指定输出目录生成 docs/ 目录后,只需几行代码就能在开发环境暴露交互式文档页面。注意:不要在生产环境启用,避免暴露内部接口细节。
import "github.com/swaggo/gin-swagger"// 在 router 初始化后添加 r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
访问 http://localhost:8080/swagger/index.html 即可查看。常见问题:
docs/swagger.json 是否存在、是否可被 HTTP 访问(路径是否拼错)swag init 未成功执行,或 handler 函数没加 @Router 注释router.Use(cors.Default())
Go 没有运行时反射泛型类型,swag 无法自动推导 Result[T] 中的 T。必须手动指定响应 schema:
// @Success 200 {object} model.Result{data=model.User} "user info"
func GetUser(c *gin.Context) {
c.JSON(200, model.Result[model.User]{Data: user})
}其中 model.Result 需标注为模型:
type Result[T any] struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data T `json:"data"`
}
// swagger:model
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}其他易漏点:
// @Failure 显式声明,否则 UI 不显示错误示例{array}model.User,不是 []model.User
// @Param xxx body model.Req true "request" 描述文档滞后是最大风险。建议在 PR 流程中加入校验步骤:提交前强制生成并 diff docs/swagger.json,不一致则拒绝合并。
Git Hook 示例( .):
#!/bin/sh swag init -o docs --quiet if ! git diff --quiet -- docs/swagger.json; then echo "ERROR: docs/swagger.json is out of date. Run 'swag init -o docs'" exit 1 fi
CI 脚本中也应包含相同逻辑,并把 docs/ 提交进仓库——Swagger UI 依赖这些静态文件,不能只靠构建时生成。
真正麻烦的是接口变更后忘记改注释,工具不会报错,但文档就和实际行为对不上了。这事只能靠 Code Review 和自动化 diff 卡住,没有银弹。
来电咨询