swag 将 Go 的注释转换为 Swagger 2.0 文档
Swag 将 Go 的注释转换为 Swagger2.0 文档。我们为流行的 Go Web Framework 创建了各种插件,这样可以与现有 Go 项目快速集成(使用 Swagger UI)。
快速开始
- 将注释添加到 API 源代码中,请参阅声明性注释格式。
- 使用如下命令下载 swag:
go install github.com/swaggo/swag/cmd/swag@latest
从源码开始构建的话,需要有 Go 环境(1.18 及以上版本)。
或者从 github 的 release 页面下载预编译好的二进制文件。
- 在包含
main.go
文件的项目根目录运行swag init
。这将会解析注释并生成需要的文件(docs
文件夹和docs/docs.go
)。
swag init
确保导入了生成的 docs/docs.go
文件,这样特定的配置文件才会被初始化。如果通用 API 注释没有写在 main.go
中,可以使用 -g
标识符来告知 swag。
swag init -g http/api.go
- (可选) 使用
fmt
格式化 SWAG 注释。(请先升级到最新版本)
swag fmt
swag cli
swag init -h NAME: swag init - Create docs.go USAGE: swag init [command options] [arguments...] OPTIONS: --generalInfo value, -g value API 通用信息所在的 go 源文件路径,如果是相对路径则基于 API 解析目录 (默认: "main.go") --dir value, -d value API 解析目录 (默认: "./") --exclude value 解析扫描时排除的目录,多个目录可用逗号分隔(默认:空) --propertyStrategy value, -p value 结构体字段命名规则,三种:snakecase,camelcase,pascalcase (默认: "camelcase") --output value, -o value 文件(swagger.json, swagger.yaml and doc.go) 输出目录 (默认: "./docs") --parseVendor 是否解析 vendor 目录里的 go 源文件,默认不 --parseDependency 是否解析依赖目录中的 go 源文件,默认不 --markdownFiles value, --md value 指定 API 的描述信息所使用的 markdown 文件所在的目录 --generatedTime 是否输出时间到输出文件 docs.go 的顶部,默认是 --codeExampleFiles value, --cef value 解析包含用于 x-codeSamples 扩展的代码示例文件的文件夹,默认禁用 --parseInternal 解析 internal 包中的 go 文件,默认禁用 --parseDepth value 依赖解析深度 (默认: 100) --instanceName value 设置文档实例名 (默认: "swagger")
swag fmt -h NAME: swag fmt - format swag comments USAGE: swag fmt [command options] [arguments...] OPTIONS: --dir value, -d value API 解析目录 (默认: "./") --exclude value 解析扫描时排除的目录,多个目录可用逗号分隔(默认:空) --generalInfo value, -g value API 通用信息所在的 go 源文件路径,如果是相对路径则基于 API 解析目录 (默认: "main.go") --help, -h show help (default: false)
支持的 Web 框架
如何与 Gin 集成
点击此处 查看示例源代码。
使用 swag init
生成 Swagger2.0 文档后,导入如下代码包:
import "github.com/swaggo/gin-swagger" // gin-swagger middleware import "github.com/swaggo/files" // swagger embed files
在 main.go
源代码中添加通用的 API 注释:
// @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 support@swagger.io // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html // @host localhost:8080 // @BasePath /api/v1 // @securityDefinitions.basic BasicAuth // @externalDocs.description OpenAPI // @externalDocs.url https://swagger.io/resources/open-api/ func main() { r := gin.Default() 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) } //... } r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) r.Run(":8080") } //...
此外,可以动态设置一些通用的 API 信息。生成的代码包 docs
导出 SwaggerInfo
变量,使用该变量可以通过编码的方式设置标题、描述、版本、主机和基础路径。使用 Gin 的示例:
package main import ( "github.com/gin-gonic/gin" "github.com/swaggo/files" "github.com/swaggo/gin-swagger" "./docs" // docs is generated by Swag CLI, you have to import it. ) // @contact.name API Support // @contact.url http://www.swagger.io/support // @contact.email support@swagger.io // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html func main() { // programatically set swagger info docs.SwaggerInfo.Title = "Swagger Example API" docs.SwaggerInfo.Description = "This is a sample server Petstore server." docs.SwaggerInfo.Version = "1.0" docs.SwaggerInfo.Host = "petstore.swagger.io" docs.SwaggerInfo.BasePath = "/v2" docs.SwaggerInfo.Schemes = []string{"http", "https"} r := gin.New() // use ginSwagger middleware to serve the API docs r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) r.Run() }
在 controller
代码中添加 API 操作注释:
package controller import ( "fmt" "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/swaggo/swag/example/celler/httputil" "github.com/swaggo/swag/example/celler/model" ) // 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] func (c *Controller) ShowAccount(ctx *gin.Context) { id := ctx.Param("id") aid, err := strconv.Atoi(id) if err != nil { httputil.NewError(ctx, http.StatusBadRequest, err) return } account, err := model.AccountOne(aid) if err != nil { httputil.NewError(ctx, http.StatusNotFound, err) return } ctx.JSON(http.StatusOK, account) } // ListAccounts godoc // @Summary List accounts // @Description get accounts // @Tags accounts // @Accept json // @Produce json // @Param q query string false "name search by q" Format(email) // @Success 200 {array} model.Account // @Failure 400 {object} httputil.HTTPError // @Failure 404 {object} httputil.HTTPError // @Failure 500 {object} httputil.HTTPError // @Router /accounts [get] func (c *Controller) ListAccounts(ctx *gin.Context) { q := ctx.Request.URL.Query().Get("q") accounts, err := model.AccountsAll(q) if err != nil { httputil.NewError(ctx, http.StatusNotFound, err) return } ctx.JSON(http.StatusOK, accounts) } //...
swag init
运行程序,然后在浏览器中访问 http://localhost:8080/swagger/index.html 。将看到 Swagger 2.0 Api 文档,如下所示:
格式化说明
可以针对 Swag 的注释自动格式化,就像 go fmt
。
此处查看格式化结果 here .
示例:
swag fmt
排除目录(不扫描)示例:
swag fmt -d ./ --exclude ./internal
通用 API 信息
注释 | 说明 | 示例 |
---|---|---|
title | 必填 应用程序的名称。 | // @title Swagger Example API |
version | 必填 提供应用程序 API 的版本。 | // @version 1.0 |
description | 应用程序的简短描述。 | // @description This is a sample server celler server. |
tag.name | 标签的名称。 | // @tag.name This is the name of the tag |
tag.description | 标签的描述。 | // @tag.description Cool Description |
tag.docs.url | 标签的外部文档的 URL。 | // @tag.docs.url https://example.com |
tag.docs.description | 标签的外部文档说明。 | // @tag.docs.description Best example documentation |
termsOfService | API 的服务条款。 | // @termsOfService http://swagger.io/terms/ |
contact.name | 公开的 API 的联系信息。 | // @contact.name API Support |
contact.url | 联系信息的 URL。 必须采用网址格式。 | // @contact.url http://www.swagger.io/support |
contact.email | 联系人/组织的电子邮件地址。 必须采用电子邮件地址的格式。 | // @contact.email support@swagger.io |
license.name | 必填 用于 API 的许可证名称。 | // @license.name Apache 2.0 |
license.url | 用于 API 的许可证的 URL。 必须采用网址格式。 | // @license.url http://www.apache.org/licenses/LICENSE-2.0.html |
host | 运行 API 的主机(主机名或 IP 地址)。 | // @host localhost:8080 |
BasePath | 运行 API 的基本路径。 | // @BasePath /api/v1 |
accept | API 可以使用的 MIME 类型列表。 请注意,Accept 仅影响具有请求正文的操作,例如 POST、PUT 和 PATCH。 值必须如“ Mime 类型 ”中所述。 | // @accept json |
produce | API 可以生成的 MIME 类型的列表。值必须如“ Mime 类型 ”中所述。 | // @produce json |
query.collection.format | 请求 URI query 里数组参数的默认格式:csv,multi,pipes,tsv,ssv。 如果未设置,则默认为 csv。 | // @query.collection.format multi |
schemes | 用空格分隔的请求的传输协议。 | // @schemes http https |
externalDocs.description | Description of the external document. | // @externalDocs.description OpenAPI |
externalDocs.url | URL of the external document. | // @externalDocs.url https://swagger.io/resources/open-api/ |
x-name | 扩展的键必须以 x-开头,并且只能使用 json 值 | // @x-example-key {"key": "value"} |
使用 Markdown 描述
如果文档中的短字符串不足以完整表达,或者需要展示图片,代码示例等类似的内容,则可能需要使用 Markdown 描述。要使用 Markdown 描述,请使用一下注释。
注释 | 说明 | 示例 |
---|---|---|
title | 必填 应用程序的名称。 | // @title Swagger Example API |
version | 必填 提供应用程序 API 的版本。 | // @version 1.0 |
description.markdown | 应用程序的简短描述。 从 api.md 文件中解析。 这是 @description 的替代用法。 | // @description.markdown No value needed, this parses the description from api.md |
tag.name | 标签的名称。 | // @tag.name This is the name of the tag |
tag.description.markdown | 标签说明,这是 tag.description 的替代用法。 该描述将从名为 tagname.md 的 文件中读取。 | // @tag.description.markdown |
API 操作
Example celler/controller
注释 | 描述 |
---|---|
description | 操作行为的详细说明。 |
description.markdown | 应用程序的简短描述。该描述将从名为 endpointname.md 的文件中读取。 |
id | 用于标识操作的唯一字符串。在所有 API 操作中必须唯一。 |
tags | 每个 API 操作的标签列表,以逗号分隔。 |
summary | 该操作的简短摘要。 |
accept | API 可以使用的 MIME 类型列表。 请注意,Accept 仅影响具有请求正文的操作,例如 POST、PUT 和 PATCH。 值必须如“ Mime 类型 ”中所述。 |
produce | API 可以生成的 MIME 类型的列表。值必须如“ Mime 类型 ”中所述。 |
param | 用空格分隔的参数。 param name , param type , data type , is mandatory? , comment attribute(optional) |
security | 每个 API 操作的 安全性 。 |
success | 以空格分隔的成功响应。 return code , {param type} , data type , comment |
failure | 以空格分隔的故障响应。 return code , {param type} , data type , comment |
response | 与 success、failure 作用相同 |
header | 以空格分隔的头字段。 return code , {param type} , data type , comment |
router | 以空格分隔的路径定义。 path , [httpMethod] |
deprecatedrouter | 与 router 相同,但是是 deprecated 的。 |
x-name | 扩展字段必须以 x- 开头,并且只能使用 json 值。 |
deprecated | 将当前 API 操作的所有路径设置为 deprecated |
Mime 类型
swag
接受所有格式正确的 MIME 类型, 即使匹配 */*
。除此之外, swag
还接受某些 MIME 类型的别名,如下所示:
Alias | MIME Type |
---|---|
json | application/json |
xml | text/xml |
plain | text/plain |
html | text/html |
mpfd | multipart/form-data |
x-www-form-urlencoded | application/x-www-form-urlencoded |
json-api | application/vnd.api+json |
json-stream | application/x-json-stream |
octet-stream | application/octet-stream |
png | image/png |
jpeg | image/jpeg |
gif | image/gif |
参数类型
- query
- path
- header
- body
- formData
数据类型
- string (string)
- integer (int, uint, uint32, uint64)
- number (float32)
- boolean (bool)
- user defined struct
安全性
注释 | 描述 | 参数 | 示例 |
---|---|---|---|
securitydefinitions.basic | Basic auth. | // @securityDefinitions.basic BasicAuth | |
securitydefinitions.apikey | API key auth. | in, name | // @securityDefinitions.apikey ApiKeyAuth |
securitydefinitions.oauth2.application | OAuth2 application auth. | tokenUrl, scope | // @securitydefinitions.oauth2.application OAuth2Application |
securitydefinitions.oauth2.implicit | OAuth2 implicit auth. | authorizationUrl, scope | // @securitydefinitions.oauth2.implicit OAuth2Implicit |
securitydefinitions.oauth2.password | OAuth2 password auth. | tokenUrl, scope | // @securitydefinitions.oauth2.password OAuth2Password |
securitydefinitions.oauth2.accessCode | OAuth2 access code auth. | tokenUrl, authorizationUrl, scope | // @securitydefinitions.oauth2.accessCode OAuth2AccessCode |
参数注释 | 示例 |
---|---|
in | // @in header |
name | // @name Authorization |
tokenUrl | // @tokenUrl https://example.com/oauth/token |
authorizationurl | // @authorizationurl https://example.com/oauth/authorize |
scope.hoge | // @scope.write Grants write access |
属性
// @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) // @Param collection query []string false "string collection" collectionFormat(multi) // @Param extensions query []string false "string collection" extensions(x-example=test,x-nullable)
也适用于结构体字段:
type Foo struct { Bar string `minLength:"4" maxLength:"16"` Baz int `minimum:"10" maximum:"20" default:"15"` Qux []string `enums:"foo,bar,baz"` }
当前可用的
字段名 | 类型 | 描述 |
---|---|---|
default | * | 声明如果未提供任何参数,则服务器将使用的默认参数值,例如,如果请求中的客户端未提供该参数,则用于控制每页结果数的“计数”可能默认为 100。 (注意:“default”对于必需的参数没有意义)。参看 https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-6.2。 与 JSON 模式不同,此值务必符合此参数的定义 类型 。 |
maximum | number | 参看 https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.1.2 . |
minimum | number | 参看 https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.1.3 . |
maxLength | integer | 参看 https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.1 . |
minLength | integer | 参看 https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.2 . |
enums | [*] | 参看 https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.1 . |
format | string | 上面提到的 类型 的扩展格式。有关更多详细信息,请参见 数据类型格式 。 |
collectionFormat | string | 指定 query 数组参数的格式。 可能的值为:
csv 。 |
进一步的
字段名 | 类型 | 描述 |
---|---|---|
multipleOf | number | See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.1.1 . |
pattern | string | See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.3 . |
maxItems | integer | See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.3.2 . |
minItems | integer | See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.3.3 . |
uniqueItems | boolean | See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.3.4 . |
样例
多行的描述
可以在常规 api 描述或路由定义中添加跨越多行的描述,如下所示:
// @description This is the first line // @description This is the second line // @description And so forth.
用户自定义的具有数组类型的结构
// @Success 200 {array} model.Account <-- This is a user defined struct.
package model type Account struct { ID int `json:"id" example:"1"` Name string `json:"name" example:"account name"` }
响应对象中的模型组合
// JSONResult 的 data 字段类型将被 proto.Order 类型替换 @success 200 {object} jsonresult.JSONResult{data=proto.Order} "desc"
type JSONResult struct { Code int `json:"code" ` Message string `json:"message"` Data interface{} `json:"data"` } type Order struct { //in `proto` package ... }
- 还支持对象数组和原始类型作为嵌套响应
@success 200 {object} jsonresult.JSONResult{data=[]proto.Order} "desc" @success 200 {object} jsonresult.JSONResult{data=string} "desc" @success 200 {object} jsonresult.JSONResult{data=[]string} "desc"
- 替换多个字段的类型。如果某字段不存在,将添加该字段。
@success 200 {object} jsonresult.JSONResult{data1=string,data2=[]string,data3=proto.Order,data4=[]proto.Order} "desc"
在响应中增加头字段
// @Success 200 {string} string "ok" // @failure 400 {string} string "error" // @response default {string} string "other error" // @Header 200 {string} Location "/entity/1" // @Header 200,400,default {string} Token "token" // @Header all {string} Token2 "token2"
使用多路径参数
/// ... // @Param group_id path int true "Group ID" // @Param account_id path int true "Account ID" // ... // @Router /examples/groups/{group_id}/accounts/{account_id} [get]
结构体的示例值
type Account struct { ID int `json:"id" example:"1"` Name string `json:"name" example:"account name"` PhotoUrls []string `json:"photo_urls" example:"http://test/image/1.jpg , http://test/image/2.jpg"` }
结构体描述
type Account struct { // ID this is userid ID int `json:"id"` Name string `json:"name"` // This is Name }
使用 swaggertype
标签更改字段类型
type TimestampTime struct { time.Time } ///实现 encoding.JSON.Marshaler 接口 func (t *TimestampTime) MarshalJSON() ([]byte, error) { bin := make([]byte, 16) bin = strconv.AppendInt(bin[:0], t.Time.Unix(), 10) return bin, nil } ///实现 encoding.JSON.Unmarshaler 接口 func (t *TimestampTime) UnmarshalJSON(bin []byte) error { v, err := strconv.ParseInt(string(bin), 10, 64) if err != nil { return err } t.Time = time.Unix(v, 0) return nil } /// type Account struct { // 使用`swaggertype`标签将别名类型更改为内置类型 integer ID sql.NullInt64 `json:"id" swaggertype:"integer"` // 使用`swaggertype`标签更改 struct 类型为内置类型 integer RegisterTime TimestampTime `json:"register_time" swaggertype:"primitive,integer"` // Array types can be overridden using "array,<prim_type>" format Coeffs []big.Float `json:"coeffs" swaggertype:"array,number"` }
type CerticateKeyPair struct { Crt []byte `json:"crt" swaggertype:"string" format:"base64" example:"U3dhZ2dlciByb2Nrcw=="` Key []byte `json:"key" swaggertype:"string" format:"base64" example:"U3dhZ2dlciByb2Nrcw=="` }
生成的 swagger 文档如下:
"api.MyBinding": { "type":"object", "properties":{ "crt":{ "type":"string", "format":"base64", "example":"U3dhZ2dlciByb2Nrcw==" }, "key":{ "type":"string", "format":"base64", "example":"U3dhZ2dlciByb2Nrcw==" } } }
使用 swaggerignore
标签排除字段
type Account struct { ID string `json:"id"` Name string `json:"name"` Ignored int `swaggerignore:"true"` }
将扩展信息添加到结构字段
type Account struct { ID string `json:"id" extensions:"x-nullable,x-abc=def,!x-omitempty"` // 扩展字段必须以"x-"开头 }
生成 swagger 文档,如下所示:
"Account": { "type": "object", "properties": { "id": { "type": "string", "x-nullable": true, "x-abc": "def", "x-omitempty": false } } }
对展示的模型重命名
type Resp struct { Code int }//@name Response
如何使用安全性注释
通用 API 信息。
// @securityDefinitions.basic BasicAuth // @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
每个 API 操作。
// @Security ApiKeyAuth
使用 AND 条件。
// @Security ApiKeyAuth // @Security OAuth2Application[write, admin]
项目地址: https://github.com/swaggo/swag
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 数据库主从架构、读写分离
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论