swag是静态注释解析器,需确保注释可扫描、docs包导入、路由挂载正确;swag init须在项目根目录执行且全局注释紧贴package main;handler注释必须含@summary;gin-swagger路由需用*any并置于业务路由后;结构体字段须导出且带json tag;生产环境应禁用/swagger/。

swag 不是运行时引擎,它是个静态注释解析器 —— 生成 docs/swagger.json 后就退出了,后续文档展示完全靠前端(Swagger UI)加载该文件。想让它“在线”可用,关键在三件事:注释能被扫到、docs 包被导入、路由挂对位置。
swag init 没生成 docs/ 目录?先盯住这三处
不是命令没跑,而是工具根本没找到 handler 或元信息。
-
swag init必须在项目根目录执行 —— 即含go.mod和入口main.go的目录;若入口在cmd/server/main.go,得加-g cmd/server/main.go - 全局注释(
@title、@version等)必须写在main.go(或-g指定的文件)里,且紧贴package main,中间不能有空行、import或块注释/* */ - 每个 handler 函数上方必须有完整注释块,且以
// @Summary开头;缺这一行,整个函数直接被跳过,docs/docs.go不更新
gin-swagger 访问 /swagger/index.html 404?路由挂载顺序和路径写法错了
这不是 Swagger UI 本身的问题,而是 Gin 没把静态资源路由注册进去。
-
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))必须放在所有业务路由之后、r.Run()之前;如果先挂 swagger 再加r.Group("/api"),子路由会覆盖/swagger/*any -
*any不能省 —— 写成/swagger/*或/swagger/都无法匹配/swagger/swagger-ui.css这类子路径 - 别用
router.Static("/swagger", "./docs"):Swagger UI 是 SPA,依赖 History API 回退,必须走ginSwagger.WrapHandler处理
@Param 或 @Success 字段不显示?结构体字段导出和 tag 冲突了
Swag 不反射字段值,只读导出字段 + json tag;小写字母开头或 json:"-" 的字段,文档里永远看不到。
- 结构体字段必须首字母大写(导出),且带
json:tag:Name string `json:"name"`→ 文档显示name: string;name string `json:"name"`(小写)→ 完全消失 -
@Param req body models.UserReq true "请求体"中的models.UserReq必须已 import,且该结构体本身也要满足导出 + tag 规则 - 数组类型要显式声明:
@Success 200 {array} models.User,不能写{object} []models.User或{array} []models.User
上线后 Swagger 页面空白或加载超时?别让 docs/swagger.json 暴露给生产环境
生成的 swagger.json 里含所有接口路径、参数、错误码甚至注释里的调试说明 —— 它不是“文档”,是接口快照。
- 开发期可保留
ginSwagger路由;上线前务必移除,或用build tag条件编译://go:build dev - 若需内部运维访问,至少加 IP 白名单或 Basic Auth 中间件;不要把
/swagger/放在公网反向代理后直接暴露 - 每次改完 handler 注释或结构体字段,都得重新跑
swag init—— 它不监听文件变化,也不增量更新
真正卡住人的,从来不是“怎么装”,而是 swag init 静默失败后,你不知道它到底扫到了哪些文件、跳过了哪些函数。建议第一次跑完后,直接打开 docs/docs.go,搜 APIPath 或 swagger:meta,确认关键 handler 是否出现在生成的结构体里。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











