Skip to content

Latest commit

 

History

History
744 lines (586 loc) · 35.8 KB

README_zh-CN.md

File metadata and controls

744 lines (586 loc) · 35.8 KB

swag

🌍 English简体中文

Travis Status Coverage Status Go Report Card codebeat badge Go Doc Backers on Open Collective Sponsors on Open Collective FOSSA Status Release

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

目录

快速开始

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

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

或者从 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

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解析目录 (默认: "./")
   --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的顶部,默认是

支持的 Web 框架

如何与 Gin 集成

点击此处查看示例源代码。

  1. 使用swag init生成 Swagger2.0 文档后,导入如下代码包:
import "github.com/swaggo/gin-swagger" // gin-swagger middleware
import "github.com/swaggo/files" // swagger embed files
  1. 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 [email protected]

// @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

// @securitydefinitions.bearerAuth BearerAuth
// @scheme bearer
// @bearerFormat JWT

// @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" // docs is generated by Swag CLI, you have to import it.
)

// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email [email protected]

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

// @termsOfService http://swagger.io/terms/

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()
}
  1. 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 a account
// @Description get string by ID
// @ID get-string-by-int
// @Accept  json
// @Produce  json
// @Param id path int true "Account ID"
// @Success 200 {object} model.Account
// @Header 200 {string} Token "qwerty"
// @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
// @Accept  json
// @Produce  json
// @Param q query string false "name search by q"
// @Success 200 {array} model.Account
// @Header 200 {string} Token "qwerty"
// @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
  1. 运行程序,然后在浏览器中访问 http://localhost:8080/swagger/index.html。将看到Swagger 2.0 Api 文档,如下所示:

swagger_index.html

开发现状

Swagger 2.0 文档

  • Basic Structure
  • API Host and Base Path
  • Paths and Operations
  • Describing Parameters
  • Describing Request Body
  • Describing Responses
  • MIME Types
  • Authentication
    • Basic Authentication
    • API Keys
  • Adding Examples
  • File Upload
  • Enums
  • Grouping Operations With Tags
  • Swagger Extensions

声明式注释格式

通用 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 [email protected]
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 请求 URI query 里数组参数的默认格式: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 接受所有格式正确的 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)

也适用于结构体字段:

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"
// @Header 200 {string} Location "/entity/1"
// @Header 200 {string} Token "qwerty"

使用多路径参数

/// ...
// @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-"开头
}

生成 swagger 文档,如下所示:

"Account": {
    "type": "object",
    "properties": {
        "id": {
            "type": "string",
            "x-nullable": true,
            "x-abc": "def"
        }
    }
}

对展示的模型重命名

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]

项目相关

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

FOSSA Status