跳到主要内容

使用 swag 来给 go 项目添加自动化构建文档。

安装

# 安装 swag 命令行工具
go install github.com/swaggo/swag/cmd/swag@latest

# 在项目中安装
go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files

cli

在包含 main.go 文件的项目根目录运行 swag init 。这将会解析注释并生成重要的文件(如 docs 文件夹和 docs/docs.go) 。

# 通常使用
swag init

# 若通用 API 未写在 main.go
swag init -g cmd/docs.go

在输入后可以使用 fmt 格式化 SWAG 注释 (需要升级到最新版本):

swag fmt

如果使用的 air 可以在 .air.toml#pre_cmd 设定 ["swag fmt", "swag init -d ./cmd,./internal -o ./docs -g ./docs.go"] 来自动化更新文档。

.air.toml
pre_cmd = ["swag fmt", "swag init -d ./cmd,./internal -o ./docs -g ./docs"]

通用注释

这类注释通常放到项目的主入口文件(如 main.go )中,用于定义 API 的全局信息。

如果未放置在默认位置( main.go ),那么需要使用 -g 指定该代码片段放置位置
swag init -g cmd/docs.go
标签说明示例
@titleAPI 文档的标题@title 我的项目 API
@versionAPI 的版本号@version 1.0
@descriptionAPI 的简要描述@description 这是一个示例项目
@termsOfServiceAPI 的服务条款@termsOfService xxx/terms
@contact.name联系方式名称@contact.name API 支持
@contact.url联系网址名称@contact.url xxxx/support
@contact.email联系邮箱名称@contact.email Mr.MudBean@outlook.com
@license.name许可证名称@license.name Apache 2.0
@license.url许可证网址@license.url xxx
@hostAPI 服务的主机地址@host localhost:8080
@BasePathAPI 的基础路径@BasePath /api/v1
@securityDefinitions.basic安全定义@securityDefinitions.basic basicAuth
@externalDocs.description外部文档描述@externalDocs.description OpenAPI
@externalDocs.url外部文档网址@externalDocs.url xxx
cmd/docs.go
package main

// @title 我的项目
// @version 1.0.2
// @description 这是一个使用 Swaggo 生成的 API 文档的 Gin 项目
// @termsOfService https://github.com/swaggo/swag/blob/master/README_zh-CN.md

// @contact.name API 支持
// @contact.url https://lmssee.com/support
// @contact.email Mr.MudBean@outlook.com

// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host localhost:9456
// @BasePath /api/v1

// @securityDefinitions.basic BasicAuth

API 接口注释

这一类注释直接写在 HTTP Handler 函数上方,用于描述具体的接口。

标签说明示例
@Summary接口的简短摘要@Summary 创建新用户
@Description接口的详细描述@Description 根据传入参数创建一个用户
@Tags用于对接口进行分组@Tags 用户管理
@Accept请求体的数据格式@Accept json
@Produce响应体的数据格式@Produce json
@Param请求参数@Param id path int true "用户 ID"
@Success成功响应@Success 200 {object} model.User
@Failure失败响应@Failure 404 {object} model.Error
@Router请求的路径和方法@Router /users/{id}/ [get]
internal/test/handler.go
// Getting go doc
//
// @Summary 获取
// @Description 简单测试 Get
// @Tags 测试
// @Accept json
// @Produce json
// @Success 200 {object} testResponse "成功响应"
// @Failure 400 {object} errno.SwagBadRequest "参数错误"
// @Failure 500 {object} errno.SwagServerError "服务器错误"
// @Router /test [get]

@Param 参数详解

完成格式:

// @Param 参数名 参数位置 数据类型 是否必填 "描述"
参数部分可选值示例
参数名自定义idusernamedata
参数位置path/query/formData/body/header---
数据类型基本类型/结构体intstringboolUserRequest
是否必填true/falsetrue
描述字符串"用户唯一标识符"
示例
// @Param id path int true "用户 ID"
// @Param name query string false "用户名"
// @Param user body userRequest true "用户信息"
// @Param Authorization header string true "认证令牌"
位置说明路由
pathURL 路径参数/users/{id}
queryURL 查询字符串/users?name=Tom&page=1
formData表单数据,包括文件上传multipart/form-data
body请求体(JSON/XML)Content-Type: application/json
headerHTTP 头---
cookieCookie---

除了基础的 required ,Swaggo 支持直接写在 @Param 或结构体中,用于生成更详细的参数约束说明(尽然 Swaggo 本身不执行校验,但文档会显示这些规则)

标签说明示例
Enum限制参数的枚举值@Param status query string false "状态" Enums(active, inactive)
Default参数的默认值@Param page query int false "页码" Default(1)
Minimum/Maximum数值范围(包含边界)@Param age query int false "年龄" Minimum(0) Maximum(120)
MinLength/MaxLength字符串长度限制@Param keyword query string false "关键字" MinLength(3) MaxLength(20)
Format指定数据格式@Param date query string false "日期" Format(date-time)
CollectionFormat数组格式@Param ids query []int false "ID 列表" CollectionFormat(multi)

如果不想为简单的请求体专门创建一个 Struct ,可以直接在注释中写 JSON 结构:

// @Param user body object true "用户信息"
// @Param user.body.name string true "用户名"
// @Param user.body.age int false "年龄"

@Success 成功响应

格式说明:

// @Success 状态码 {返回类型} 数据类型 "描述"

示例:

// 返回对象
// @Success 200 {object} UserResponse "成功返回用户信息"
// @Success 201 {object} CreateUserResponse "创建成功"
// @Success 204 "删除成功,无返回内容"

// 返回数组
// @Success 200 {array} User "返回用户列表"
// @Success 200 {array} model.User "返回模型数组"

// 返回分页数据
// @Success 200 {object} Pagination{data=[]User} "分页数据"
// @Success 200 {object} CommonResponse{data=[]User} "通用返回格式"

// 基本类型
// @Success 200 {string} string "返回字符串"
// @Success 200 {int} int "返回整数"
// @Success 200 {boolean} bool "返回布尔值"
// @Success 200 {file} file "返回文件"

// 自定义响应头
// @Success 200 {string} string "操作成功" Header(X-RateLimit-Limit,int,请求限制) Header(X-RateLimit-Remaining,int,剩余次数)


// 自定义分页结构
type Pagination struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
Total int64 `json:"total"`
Data interface{} `json:"data"`
}

// 在注释中使用
// @Success 200 {object} Pagination{data=[]User,total=int64} "分页用户列表"

@Failure 错误响应

格式说明:

// @Failure 状态码 {返回类型} 数据类型 "描述"

完整示例:

// @Failure 400 {object} ErrorResponse "请求参数错误"
// @Failure 401 {object} ErrorResponse "未授权"
// @Failure 403 {object} ErrorResponse "禁止访问"
// @Failure 404 {object} ErrorResponse "资源不存在"
// @Failure 500 {object} ErrorResponse "服务器内部错误"


// 定义标准错误响应
type ErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Details string `json:"details,omitempty"`
}

// 多错误状态码
// @Failure 400,404,500 {object} ErrorResponse "错误响应"

// 无返回体
// @Failure 429 "请求过于频繁,请稍后重试"

// 带响应头
// @Failure 429 {string} string "请求过于频繁" Header(Retry-After,int,重试等待秒数)

@Router 路由定义

格式说明:

// @Router 路径 [HTTP 方法] [分组]

完整示例:

// 基本格式
// @Router /users [post]
// @Router /users/{id} [get]
// @Router /users/{id} [put]
// @Router /users/{id} [delete]

// 带路径参数
// @Router /users/{id}/orders/{order_id} [get]

// 查询参数(不在Router中定义)
// @Router /users [get] # 对应 /users?name=xxx&page=1

// 路由分组(可选)
// @Router /api/v1/users [get] [用户管理]

// RESTful风格示例
// 创建用户
// @Router /users [post]
// 获取用户列表
// @Router /users [get]
// 获取单个用户
// @Router /users/{id} [get]
// 更新用户
// @Router /users/{id} [put]
// 删除用户
// @Router /users/{id} [delete]

@Accept

swag 接受多有正确的 MIME 类型,即使匹配 */*

AliasMIME TYPE
jsonapplication/json
xmltext/xml
plaintext/plain
htmltext/html
mpfdmultipart/form-data
x-www-form-urlencodedapplication/x-www-form-urlencoded
json-apiapplication/vnd.api+json
json-streamapplication/x-json-stream
octet-streamapplication/octet-stream
pngimage/png
jepgimage/jpeg
gifimage/gif
event-streamtext/event-stream
// 单个类型
// @Accept json
// @Accept xml
// @Accept mpfd # multipart/form-data
// @Accept x-www-form-urlencoded
// @Accept plain
// @Accept html

// 多个类型
// @Accept json
// @Accept xml
// 或
// @Accept json,xml

// 实际应用示例
// POST /users 创建用户
// @Accept json
// 对应 Header: Content-Type: application/json

@Produce

// 单个类型
// @Produce json
// @Produce xml
// @Produce plain
// @Produce html
// @Produce png
// @Produce pdf
// @Produce octet-stream # 二进制流

// 多个类型
// @Produce json
// @Produce xml
// 对应 Header: Content-Type: application/json 或 application/xml
// 根据客户端 Accept 头协商返回

// 常用组合
// @Accept json
// @Produce json

@Summary@Description

// @Summary 简短摘要
// @Description 详细描述
// 支持多行
// 这是第二行描述
// 还可以使用Markdown格式
// - 列表项1
// - 列表项2
// 代码示例: `fmt.Println("hello")`

结构体字段注释

标签说明示例
example字段的示例值Name string json:"name" example:"张三"
required标记字段为必填Email string json:"email" required:"true"
enum定义字段的枚举值Status string json:"status" enum:"active,inactive"
minimum/maximum数值的最小/最大值Age int json:"age" minimum:"0" maximum:"120"
swaggerignore忽略该字段,不生成文档InternalID int swaggerignore:"true"
// 请求体示例
// @Param request body CreateUserRequest true "创建用户请求" example({"name":"张三","age":20})

// 模型示例
type CreateUserRequest struct {
// 用户名
// Required: true
// Example: 张三
Name string `json:"name" binding:"required"`

// 年龄
// Minimum: 0
// Maximum: 150
// Example: 20
Age int `json:"age"`

// 邮箱
// Format: email
// Example: user@example.com
Email string `json:"email" binding:"required,email"`
}

安全与认证标签

如果 API 需要鉴权( 如 JWT 、 OAuth2 、 Basic Auth ),这可能需要下面的标签

标签说明示例
@SecurityDefinitions定义安全机制的类型(放在 main.go@SecurityDefinitions.apikey Bearer
@in定义 Token 传递的位置(配合第一个)@in header
@name定义 Token 的 Header 名称(配合第一个)@name Authorization
@Security在具体的接口上声明需要哪种安全机制@Security Bearer
// ------ main.go 文件 ------
// @SecurityDefinitions.apikey Bearer
// @in header
// @name Authorization


// ----- 在具体的 Handler -----
// @security Bearer
// @Summary 获取个人信息

自定义扩展标签

Swagger 规范允许使用 x- 开头的字段进行扩展。常用于对接云服务( 如 AWS API Gateway )或添加自定义元数据。

标签说明示例
@x-example为字段或响应提供具体的 JSON 示例@x-example {"id": 1 , "name": "test"}
@x-nullable标记字段可以为 nullextensions: "x-nullable" 需要结合结构体标签
@x-codeSamples在文档中展示代码示例--
@x-tagGroups对左侧大的 Tags 进行分组显示---
// @x-codeSamples [
// @x-codeSamples { "lang": "curl", "source": "curl -X GET http://localhost:8080/users" },
// @x-codeSamples { "lang": "javascript", "source": "fetch('/users')" }
// @x-codeSamples ]
// @Router /users [get]