必须严格按三步走:装工具、写注释、引包注册;漏任一环swag init静默失败,/swagger/index.html显示404或空白页。

直接能用,但必须严格按三步走:装工具、写注释、引包注册。漏掉任何一环,swag init 会静默失败,浏览器打开 /swagger/index.html 是 404 或空白页。
安装 swag CLI 和 gin-swagger 依赖
不是 go get 就完事——新版 Go(1.16+)要求用 go install 安装命令行工具,否则 swag 命令根本找不到:
go install github.com/swaggo/swag/cmd/swag@latestgo get -u github.com/swaggo/gin-swaggergo get -u github.com/swaggo/files
装完立刻执行 swag -v 验证。如果报 command not found,八成是 $GOPATH/bin 没进 PATH,别硬试,先加路径。
注意:github.com/swaggo/files 是 Swagger UI 的静态资源,不是 swaggerFiles 包名——导入时 alias 成 swaggerFiles 是约定俗成,但包本身叫 files。
在 main.go 里写全局 API 注释并导入 docs 包
全局注释必须出现在 main.go 文件顶部(函数外),且必须包含 @title 和 @version,否则 swag init 会生成空文档:
// @title 用户服务 API // @version 1.0 // @description 用户增删改查接口文档 // @host localhost:8080 // @BasePath /api/v1 // @schemes http package main
紧接着,在 import 列表里加一行 _ "your-module-name/docs"(模块名来自 go.mod 第一行),这个下划线导入是关键:它触发 docs/docs.go 的 init() 函数,把文档数据注册进内存。不加这行,路由能跑通,但 Swagger 页面永远加载不出内容。
常见错误:把 docs 包名写错,比如写成 _ "./docs" 或 _ "docs" —— 必须和 go.mod 里声明的模块全名一致。
给 handler 函数写 Swag 注释并运行 swag init
每个路由 handler 上的注释决定接口在文档里长什么样。最易错的是参数类型和位置写反:
-
@Param username query string true "用户名"表示 URL 查询参数(?username=xxx) -
@Param id path int true "用户ID"表示路径参数(/users/{id}) -
@Param user body User true "用户对象"表示 JSON 请求体,User必须是已定义结构体,且包名要写全(如models.User)
执行 swag init 时,默认只扫当前目录(含子目录),但不会进 vendor 或 internal。如果 handler 分散在 handlers/ 下,加 -d ./ 显式指定根目录;如果用了 go.work 多模块,确保 swag init 在主模块根目录运行。
生成后检查 docs/swagger.json 是否有内容——空文件说明注释格式错(比如少了个空格、换行不对)或没找到 handler 函数。
注册 Swagger 路由并确认访问路径
注册代码必须放在 r.Run() 之前,且路径要带通配符:
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
这里 /swagger/*any 是 Gin 的通配路由写法,*any 表示匹配所有子路径(/swagger/index.html、/swagger/swagger.json 等)。写成 /swagger/ 或 /docs/ 都不行。
启动服务后,浏览器访问地址必须是 http://localhost:8080/swagger/index.html(不是 /docs,也不是 /swagger 不带 /index.html)。如果页面白屏,打开浏览器控制台,看是否 404 了 swagger-ui-bundle.js —— 那基本是 github.com/swaggo/files 版本和 gin-swagger 不匹配,降级到 v1.5.1 试试。
真正容易被忽略的是:每次改了注释,必须重新跑 swag init;而每次改了 main.go 里的全局注释,也得重跑——因为 docs/docs.go 是生成出来的,不重建就不会更新。

















