2025年4月15日 星期二 乙巳(蛇)年 正月十六 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Go语言

swag 将 Go 的注释转换为 Swagger 2.0 文档

时间:12-14来源:作者:点击数:8

Swag 将 Go 的注释转换为 Swagger2.0 文档。我们为流行的 Go Web Framework 创建了各种插件,这样可以与现有 Go 项目快速集成(使用 Swagger UI)。

快速开始

  1. 将注释添加到 API 源代码中,请参阅声明性注释格式。
  2. 使用如下命令下载 swag:
  • go install github.com/swaggo/swag/cmd/swag@latest

从源码开始构建的话,需要有 Go 环境(1.18 及以上版本)。

或者从 github 的 release 页面下载预编译好的二进制文件。

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

确保导入了生成的 docs/docs.go 文件,这样特定的配置文件才会被初始化。如果通用 API 注释没有写在 main.go 中,可以使用 -g 标识符来告知 swag。

  • swag init -g http/api.go
  1. (可选) 使用 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 信息

示例 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
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 - 逗号分隔值 foo,bar .
  • ssv - 空格分隔值 foo bar .
  • tsv - 制表符分隔值 foo\tbar .
  • pipes - 管道符分隔值 foo|bar .
  • multi - 对应于多个参数实例,而不是单个实例 foo=bar&foo=baz 的多个值。这仅对“ query ”或“ formData ”中的参数有效。
默认值是 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 标签更改字段类型

#201

  • 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"`
  • }

#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,!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 ​

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐