swag 实战指南:用 celler 示例项目从零生成 Swagger 2.0 文档并跑通 Gin API

发布时间:2026/9/15 20:22:16
swag 实战指南:用 celler 示例项目从零生成 Swagger 2.0 文档并跑通 Gin API
swag 实战指南用 celler 示例项目从零生成 Swagger 2.0 文档并跑通 Gin API【免费下载链接】swagAutomatically generate RESTful API documentation with Swagger 2.0 for Go.项目地址: https://gitcode.com/GitHub_Trending/sw/swag导读本指南以 swag 仓库内置的 example/celler 完整可运行示例为主线带你走通「安装 swag 命令行工具 → 在 Gin 处理器上书写注解 →swag init生成文档 → 启动服务并访问 Swagger UI」的完整链路。读完本文你将掌握 swag 生成 API 文档的全部核心注解语法全局元数据、参数、响应、安全定义、枚举与校验约束并能在自己的 Gin 项目中直接复用这套最佳实践。一、celler 示例项目是什么celler 是 swag 官方维护的一个酒窖cellar主题示例用 Gin 实现了 accounts账户、bottles酒瓶、admin管理员与 examples各类注解演示四组 RESTful 接口并在每个处理器上方书写了几乎覆盖全部 swag 注解用法的注释块。整个示例是一个独立可运行的 Go module其 go.mod 声明于 example/celler/go.mod模块名为github.com/swaggo/swag/example/celler依赖 Gin v1.9.1、swag 及配套的swaggo/filesSwagger UI 静态资源与swaggo/gin-swaggerGin 集成中间件。项目目录结构example/celler/ ├── main.go # 程序入口全局元数据注解 路由注册 Swagger UI ├── controller/ # 各处理器及 swag 接口注解 │ ├── accounts.go # 账户 CRUD 文件上传 │ ├── admin.go # 管理员鉴权接口 │ ├── bottles.go # 酒瓶查询接口 │ ├── controller.go # Controller 结构体与公共 Message 类型 │ └── examples.go # 参数类型、校验、枚举、安全等注解演示 ├── docs/ # swag init 生成产物docs.go swagger 目录 ├── httputil/error.go # 统一错误响应模型 HTTPError ├── model/ # 领域模型Account/Bottle/Admin/AddAccount… └── README.md # 官方使用说明二、环境准备与生成文档按 example/celler/README.md 的说明文档生成只需两步。第一步安装 swag 命令行工具$ go get -u github.com/swaggo/swag/cmd/swag第二步在项目根目录即包含main.go的example/celler/执行$ swag initswag init会递归扫描当前目录下所有 Go 源文件中的 swag 注解解析出 OpenAPI/Swagger 2.0 规范并默认生成三个产物到docs/目录docs/docs.go将 Swagger 文档以 Go 代码形式打包进二进制供ginSwagger运行时加载docs/swagger.jsonSwagger 2.0 JSON 规范文件docs/swagger.yaml同内容的 YAML 版本便于人工审阅。仓库当前已提交了由该命令生成的 example/celler/docs/docs.go 与 example/celler/docs/swagger/swagger.yaml 作为参考产物。你可以先运行命令再对比生成结果确认注解是否被正确解析。三、全局 API 元数据main.go 顶部的仓库级注解swag 允许在任意源文件的注释中声明 API 的全局信息约定俗成放在main()所在文件顶部。celler 示例在 example/celler/main.go 集中演示了全套全局注解// title Swagger Example API // version 1.0 // description This is a sample server celler server. // termsOfService http://swagger.io/terms/ // contact.name API Support // contact.url http://www.swagger.io/support // contact.email supportswagger.io // license.name Apache 2.0 // license.url http://www.apache.org/licenses/LICENSE-2.0.html // host localhost:8080 // BasePath /api/v1各注解含义如下注解作用示例取值titleAPI 文档标题显示在 Swagger UI 顶部Swagger Example APIversionAPI 版本号1.0description接口整体描述This is a sample server celler server.termsOfService服务条款 URLhttp://swagger.io/terms/contact.*维护者联系方式name/url/emailAPI Supportlicense.*许可证名称与地址Apache 2.0host服务主机与端口覆盖 Swagger UI 中默认的请求地址localhost:8080BasePath所有路由的公共前缀与路由注册保持一致/api/v1注意host、BasePath与 main.go 中的路由分组 是严格对应的路由实际挂在/api/v1分组下文档中的接口路径也以/api/v1为前缀两者一致才能保证 Swagger UI 里Try it out请求能够直接命中真实服务。3.1 安全定义securityDefinitions紧接其后的是一组安全方案声明示例覆盖了 Swagger 2.0 支持的全部四种 OAuth2 流程以及 Basic、API Key 两种常见方式// securityDefinitions.basic BasicAuth // securityDefinitions.apikey ApiKeyAuth // in header // name Authorization // description Description for what is this security definition being used // securitydefinitions.oauth2.application OAuth2Application // tokenUrl https://example.com/oauth/token // scope.write Grants write access // scope.admin Grants read and write access to administrative information // securitydefinitions.oauth2.implicit OAuth2Implicit // authorizationUrl https://example.com/oauth/authorize // scope.write Grants write access // securitydefinitions.oauth2.password OAuth2Password // tokenUrl https://example.com/oauth/token // scope.read Grants read access // securitydefinitions.oauth2.accessCode OAuth2AccessCode // tokenUrl https://example.com/oauth/token // authorizationUrl https://example.com/oauth/authorize // scope.admin Grants read and write access to administrative information其中securityDefinitions.apikey需要搭配in取值header或query与name如Authorization指明密钥的传递位置OAuth2 各流程则需要按规范给出tokenUrl、authorizationUrl以及若干scope.xxx作用域声明。这些定义会在后续接口级注解中通过Security被引用见 6.4 节。四、路由注册与 Swagger UI 挂载main()中先创建 Controller再按资源分组注册路由c : controller.NewController() v1 : r.Group(/api/v1) { accounts : v1.Group(/accounts) { accounts.GET(:id, c.ShowAccount) accounts.GET(, c.ListAccounts) accounts.POST(, c.AddAccount) accounts.DELETE(:id, c.DeleteAccount) accounts.PATCH(:id, c.UpdateAccount) accounts.POST(:id/images, c.UploadAccountImage) } bottles : v1.Group(/bottles) { bottles.GET(:id, c.ShowBottle) bottles.GET(, c.ListBottles) } admin : v1.Group(/admin) { admin.Use(auth()) admin.POST(/auth, c.Auth) } examples : v1.Group(/examples) { examples.GET(ping, c.PingExample) examples.GET(calc, c.CalcExample) examples.GET(groups/:group_id/accounts/:account_id, c.PathParamsExample) examples.GET(header, c.HeaderExample) examples.GET(securities, c.SecuritiesExample) examples.GET(attribute, c.AttributeExample) } } r.GET(/swagger/*any, ginSwagger.WrapHandler(swaggerFiles.Handler)) r.Run(:8080)关键点有三每个处理器的Router注解必须与这里的实际路由一致例如Router /accounts/{id} [get]对应accounts.GET(:id, ...)swag 据此生成 path 与 HTTP 方法的映射。admin分组通过admin.Use(auth())挂了一个中间件auth() 函数 要求请求头必须携带非空的Authorization否则返回 401——这是对接口鉴权的运行时实现与文档中的Security ApiKeyAuth注解形成文档声明 运行强制的双重保障。最后一行r.GET(/swagger/*any, ginSwagger.WrapHandler(swaggerFiles.Handler))将 Swagger UI 挂载到/swagger路径依赖swaggo/files与swaggo/gin-swagger两个官方配套库。五、接口级注解详解以 accounts 为例每个处理器的注释块即一份独立的接口文档声明。以 example/celler/controller/accounts.go 中的ShowAccount为例// ShowAccount godoc // // Summary Show an account // Description get string by ID // Tags accounts // Accept json // Produce json // Param id path int true Account ID // Success 200 {object} model.Account // Failure 400 {object} httputil.HTTPError // Failure 404 {object} httputil.HTTPError // Failure 500 {object} httputil.HTTPError // Router /accounts/{id} [get]逐项拆解Summary/Description接口的标题与详细说明展示在 Swagger UI 的接口列表中Tags用于在 UI 中按模块分组归类值为accounts多个标签用逗号分隔如admin.go中写作Tags accounts,adminAccept/Produce请求与响应的内容类型常见取值json、xml、plain、multipart/form-dataParam参数声明完整格式为Param 参数名 位置 类型 是否必填 描述 扩展属性位置可取path、query、header、body、formDataSuccess/Failure状态码与响应模型格式为Success 200 {object} model.Account{object}表示引用模型类型{array}表示数组{string}/{integer}表示基础类型Router路由路径与 HTTP 方法格式为Router 路径 [方法]路径中的动态段用{}包裹。5.1 完整 CRUD 一览accounts 分组覆盖了增删改查与文件上传注解分别演示了不同位置的参数查询参数ListAccountsGET /accounts// Param q query string false name search by q Format(email)body 请求体AddAccountPOST /accountsParam account body model.AddAccount true Add account表示请求体是一个model.AddAccountJSON 对象path 参数 bodyUpdateAccountPATCH /accounts/{id}同时出现Param id path int true Account ID与Param account body model.UpdateAccount true Update accountpath 参数 formData 文件UploadAccountImagePOST /accounts/{id}/imagesAccept multipart/form-data与Param file formData file true account image配合使用展示文件上传接口的文档写法其响应模型为controller.Message。值得注意DeleteAccount的成功响应声明为Success 204 {object} model.Account与实现中ctx.JSON(http.StatusNoContent, gin.H{})返回 204 空响应保持一致说明注解并非模板需要与真实行为对齐。六、bottles、admin 与 examples更多注解范式6.1 bottles数组响应与错误码声明example/celler/controller/bottles.go 的ListBottles展示了数组响应// Success 200 {array} model.Bottle // Failure 400 {object} httputil.HTTPError // Failure 404 {object} httputil.HTTPError // Failure 500 {object} httputil.HTTPError // Router /bottles [get]{array} model.Bottle会生成type: array, items: {$ref: Bottle}的 schema对应实现中model.BottlesAll()返回[]Bottle。6.2 admin运行时鉴权 接口级安全引用example/celler/controller/admin.go 的Auth接口在文档层面声明了安全要求// Security ApiKeyAuth // Router /admin/auth [post]Security ApiKeyAuth引用了 3.1 节中通过securityDefinitions.apikey定义的安全方案Swagger UI 会据此显示Authorize按钮运行时则由admin.Use(auth())中间件强制校验请求头两者共同构成接口保护的完整闭环。6.3 examples参数校验、枚举与多段路径example/celler/controller/examples.go 是注解语法的百科全书多 path 参数PathParamsExampleGET /examples/groups/{group_id}/accounts/{account_id}同一路由声明两个Param ... path ...演示多段动态路径的文档写法header 参数HeaderExampleParam Authorization header string true Authentication header声明请求头参数枚举与数值/长度约束AttributeExample// Param enumstring query string false string enums Enums(A, B, C) // Param enumint query int false int enums Enums(1, 2, 3) // Param enumnumber query number false int enums Enums(1.1, 1.2, 1.3) // Param string query string false string valid minlength(5) maxlength(10) // Param int query int false int valid minimum(1) maximum(10) // Param default query string false string default default(A)Enums(A, B, C)生成参数的枚举取值列表minlength/maxlength、minimum/maximum、default分别生成长度、数值范围与默认值约束。这些都是 Swagger 规范中 Parameter Object 的对应字段UI 上会直接呈现为可校验的输入控件多个安全方案组合SecuritiesExample// Security ApiKeyAuth // Security OAuth2Implicit[admin, write]第二个Security通过方案名[scope1, scope2]的语法为 OAuth2 方案指定所需作用域。七、模型层example 与 format 标签如何进入文档swag 会从结构体字段的json、example、format标签提取 schema 信息。以 example/celler/model/account.go 的Account为例type Account struct { ID int json:id example:1 format:int64 Name string json:name example:account name UUID uuid.UUID json:uuid example:550e8400-e29b-41d4-a716-446655440000 format:uuid }example标签为字段提供示例值直接展示在 Swagger UI 的响应示例中format标签标注 OpenAPI 扩展格式如int64、uuid提升规范精确度字段类型int/string/嵌套结构体由 swag 根据 Go 类型自动推导。model/bottle.go 中的Bottle还包含嵌套结构体字段Account Accountswag 会将其展开为嵌套的 object schema。八、统一错误模型让 400/404/500 有据可查所有接口的Failure都统一引用 example/celler/httputil/error.go 中的HTTPErrortype HTTPError struct { Code int json:code example:400 Message string json:message example:status bad request }配套的NewError(ctx, status, err)辅助函数负责把错误包装为该结构并写回响应。这意味着文档中声明的错误响应结构code message与实际线上返回的 JSON 完全一致——这是值得在业务项目中复用的模式先定义一个全局错误模型再让所有Failure引用它避免每个接口各写一套错误格式。九、运行应用与访问 Swagger UI按 README 完成swag init之后在example/celler/目录运行$ go run main.go服务启动后监听:8080打开 Swagger UIhttp://localhost:8080/swagger/index.html对应 README 中的 open swagger 链接由于host localhost:8080与BasePath /api/v1已在全局元数据中声明UI 中所有接口路径都带/api/v1前缀可直接点击接口并执行 Try it out 发起真实请求对于带鉴权的接口如/admin/auth需先通过 UI 右上角 Authorize 按钮填入Authorization请求头示例代码要求其值恰为admin与运行时中间件的校验逻辑对应。十、工作流小结把 celler 示例的方法沉淀为通用流程可用于你自己的任何 Gin 项目在 main 入口注释中声明全局元数据title、version、host、BasePath、contact、license 与 securityDefinitions为每个处理器函数书写接口级注解Summary、Tags、Accept/Produce、Parampath/query/header/body/formData、Success/Failure、Router在模型结构体上补充example与format标签提升文档示例质量统一错误响应模型让所有Failure指向同一个结构执行swag init生成docs/产物并在 main 中通过ginSwagger.WrapHandler(swaggerFiles.Handler)挂载 UIgo run main.go启动后访问http://localhost:8080/swagger/index.html验证文档。celler 示例本身的 docs/swagger/swagger.yaml 是命令生成结果的权威样例遇到注解写了但文档没生效的问题时可以对照该文件确认某个注解是否被正确解析再回头排查自己的注释格式。输出文章【免费下载链接】swagAutomatically generate RESTful API documentation with Swagger 2.0 for Go.项目地址: https://gitcode.com/GitHub_Trending/sw/swag创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考