前言
下面是需要用到的工具和库。
名称 | 描述 |
---|
swag | 使用Swagger 2.0为Go语言自动生成RESTful API文档 |
gin-swagger | gin中间件以使用Swagger 2.0自动生成RESTful API文档 |
swag是Golang的工具,将代码注释转换为Swagger2.0文档。除了swag,还需一个web框架的中间件包装器库,当前,swag支持的web框架包括gin、echo、buffalo、net/http,对于不同的框架来说,注释都是一样的。
在这里使用的是gin-swagger,另一个Golang Swagger库go-swagger,它似乎更受欢迎并且功能也更强大。
- gin-swagger:简单易用
- go-swagger:对生成的内容进行更多的控制
swag工具的README很详细。
下面把它翻译成中文,便于日后查看。
Swag

Swag将Go的注释转换为Swagger2.0文档。我们为流行的 Go Web Framework 创建了各种插件,这样可以与现有Go项目快速集成(使用Swagger UI)。
目录
快速开始
- 将注释添加到API源代码中,请参阅声明性注释格式。
- 使用如下命令下载swag:
go get -u github.com/swaggo/swag/cmd/swag
从源码开始构建的话,需要有Go环境(1.9及以上版本)。
或者从github的release页面下载预编译好的二进制文件。
- 在包含
main.go
文件的项目根目录运行swag init
。这将会解析注释并生成需要的文件(docs
文件夹和docs/docs.go
)。
确保导入了生成的docs/docs.go
文件,这样特定的配置文件才会被初始化。如果通用API指数没有写在main.go
中,可以使用-g
标识符来告知swag。
swag cli
| swag init -h |
| NAME: |
| swag init - Create docs.go |
| |
| USAGE: |
| swag init [command options] [arguments...] |
| |
| OPTIONS: |
| --generalInfo value, -g value Go file path in which 'swagger general API Info' is written (default: "main.go") |
| --dir value, -d value Directory you want to parse (default: "./") |
| --propertyStrategy value, -p value Property Naming Strategy like snakecase,camelcase,pascalcase (default: "camelcase") |
| --output value, -o value Output directory for all the generated files(swagger.json, swagger.yaml and doc.go) (default: "./docs") |
| --parseVendor Parse go files in 'vendor' folder, disabled by default |
| --parseDependency Parse go files in outside dependency folder, disabled by default |
| --markdownFiles value, --md value Parse folder containing markdown files to use as description, disabled by default |
| --generatedTime Generate timestamp at the top of docs.go, true by default |
支持的Web框架
如何与Gin集成
点击此处查看示例源代码。
- 使用
swag init
生成Swagger2.0文档后,导入如下代码包:
| import "github.com/swaggo/gin-swagger" |
| import "github.com/swaggo/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 |
| // @query.collection.format multi |
| |
| // @securityDefinitions.basic BasicAuth |
| |
| // @securityDefinitions.apikey ApiKeyAuth |
| // @in header |
| // @name Authorization |
| |
| // @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 |
| // @scope.admin Grants read and write access to administrative information |
| |
| // @securitydefinitions.oauth2.password OAuth2Password |
| // @tokenUrl https://example.com/oauth/token |
| // @scope.read Grants read access |
| // @scope.write Grants write access |
| // @scope.admin Grants read and write access to administrative information |
| |
| // @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 |
| |
| // @x-extension-openapi {"example": "value on a json format"} |
| |
| 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" |
| ) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| func main() { |
| |
| |
| 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() |
| |
| |
| 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" |
| ) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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) |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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) |
| } |
| |
| |
- 运行程序,然后在浏览器中访问 http://localhost:8080/swagger/index.html。将看到Swagger 2.0 Api文档,如下所示:

开发现状
Swagger 2.0 文档
声明式注释格式
通用API信息
示例 celler/main.go
注释 | 说明 | 示例 |
---|
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 |
query.collection.format | 查询或枚举中的默认集合(数组)参数格式:csv,multi,pipes,tsv,ssv。 如果未设置,则默认为csv。 | // @query.collection.format multi |
schemes | 用空格分隔的请求的传输协议。 | // @schemes http https |
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 的文件中读取。 | // @description.file endpoint.description.markdown |
id | 用于标识操作的唯一字符串。在所有API操作中必须唯一。 | |
tags | 每个API操作的标签列表,以逗号分隔。 | |
summary | 该操作的简短摘要。 | |
accept | API可以使用的MIME类型的列表。值必须如“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 | |
header | 以空格分隔的头字段。 return code ,{param type} ,data type ,comment | |
router | 以空格分隔的路径定义。 path ,[httpMethod] | |
x-name | 扩展字段必须以x- 开头,并且只能使用json值。 | |
Mime类型
swag
g接受所有格式正确的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 |
属性
也适用于结构体字段:
| type Foo struct { |
| Bar string `minLength:"4" maxLength:"16"` |
| Baz int `minimum:"10" maximum:"20" default:"15"` |
| Qux []string `enums:"foo,bar,baz"` |
| } |
当前可用的
进一步的
样例
多行的描述
可以在常规api描述或路由定义中添加跨越多行的描述,如下所示:
用户自定义的具有数组类型的结构
| package model |
| |
| type Account struct { |
| ID int `json:"id" example:"1"` |
| Name string `json:"name" example:"account name"` |
| } |
响应中的模型组成
| |
| @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 { |
| ... |
| } |
| @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"
在响应中增加头字段
使用多路径参数
结构体的示例值
| 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 int `json:"id"` |
| Name string `json:"name"` |
| } |
在被支持的自定义类型中使用swaggertype
标签
#201
| type TimestampTime struct { |
| time.Time |
| } |
| |
| |
| func (t *TimestampTime) MarshalJSON() ([]byte, error) { |
| bin := make([]byte, 16) |
| bin = strconv.AppendInt(bin[:0], t.Time.Unix(), 10) |
| return bin, nil |
| } |
| |
| 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 { |
| |
| ID sql.NullInt64 `json:"id" swaggertype:"integer"` |
| |
| |
| RegisterTime TimestampTime `json:"register_time" swaggertype:"primitive,integer"` |
| |
| |
| Coeffs []big.Float `json:"coeffs" swaggertype:"array,number"` |
| } |
#379
| 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"` |
| } |
生成swagger文档,如下所示:
| "Account": { |
| "type": "object", |
| "properties": { |
| "id": { |
| "type": "string", |
| "x-nullable": true, |
| "x-abc": "def" |
| } |
| } |
| } |
对展示的模型重命名
| type Resp struct { |
| Code int |
| } |
如何使用安全性注释
通用API信息。
每个API操作。
使用AND条件。
| // @Security ApiKeyAuth |
| // @Security OAuth2Application[write, admin] |
项目相关
This project was inspired by yvasiyarov/swagger but we simplified the usage and added support a variety of web frameworks. Gopher image source is tenntenn/gopher-stickers. It has licenses creative commons licensing.
贡献者
This project exists thanks to all the people who contribute. [Contribute].

支持者
Thank you to all our backers! 🙏 [Become a backer]

赞助商
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

License
