swaggo/swag

swaggo/swag 提供了Go版本的Swagger自動生產RESTful API文檔,其做法是在代碼中按Swaggo的格式編寫API注釋,然后Swaggo會去解析這些注釋,生成Swagger的文檔以及托管到Web的框架代碼,最終將代碼編譯到Web應用中,達到API文檔托管的目的。

go-swagger是一套完整且功能齊全的高性能API組件,可與Swagger-API一起使用,分為三塊分別是服務端、客戶端、數據模型。

swagger

Swagger優(yōu)勢

  • 支持API自動生成同步的在線文檔,使用Swagger后可直接通過代碼生成文檔,無需手動編寫接口文檔。
  • 提供Web頁面的在線測試API,僅需定義好參數和格式,直接在界面上輸入參數對應的值即可在線測試接口。

swaggo

  • swag命令可以將Go的注釋轉換為Swagger文檔
  • swaggo支持的Web框架包括gin、echo、buffalo、net/http。

swaggo使用前需安裝swag腳手架命令行工具、HTTP服務器、模板

$ go get -u -v github.com/swaggo/swag/cmd/swag
$ go get -u -v github.com/swaggo/http-swagger
$ go get -u -v github.com/alecthomas/template
  • swag庫將Go批注轉換為Swagger文檔,隨后由http-swagger使用,為SwaggerUI提供服務。
  • http-swagger庫使用swag生成的文檔幫助提供SwaggerUI
  • template庫用于安裝模板,這是Go的text/template包的分支,swag生成的docs.go文件中需此依賴關系,而在沒有該依賴關系的情況下運行應用程序時會得到一個錯誤。

swag

安裝Swag命令行

使用Swaggo首先要下載一個Swag命令行(腳手架)

$ go get -u -v github.com/swaggo/swag/cmd/swag

安裝成功后會在GOPATH下的bin文件夾內生成swag.exe命令行工具

$ swag --version
swag version v1.7.8

安裝最新版本

$ go install -v github.com/swaggo/swag/cmd/swag@latest
$ swag -v
swag version v1.7.8

在包含main.go主入口的工程根目錄下執(zhí)行swag init初始化,swag會檢索當前工程中的swag注釋。

$ cd gwf
$ swag init

執(zhí)行swag init命令后會在項目根目錄下生成docs文件夾,同時文件夾下會生成三個文件docs.go、swagger.json、swagger.yaml

查看swag命令支持的選項

$ swag --help
NAME:
   swag - Automatically generate RESTful API documentation with Swagger 2.0 for Go.

USAGE:
   swag [global options] command [command options] [arguments...]

VERSION:
   v1.7.8

COMMANDS:
   init, i  Create docs.go
   fmt, f   format swag comments
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help (default: false)
   --version, -v  print the version (default: false)

swag init

$ swag init --help
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                  Directories you want to parse,comma separated and general-info file must be in the first one (default: "./")
   --exclude value                        Exclude directories and files when searching, comma separated
   --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 (default: false)
   --parseDependency, --pd                Parse go files inside dependency folder, disabled by default (default: false)
   --markdownFiles value, --md value      Parse folder containing markdown files to use as description, disabled by default
   --codeExampleFiles value, --cef value  Parse folder containing code example files to use for the x-codeSamples extension, disabled by default
   --parseInternal                        Parse go files in internal packages, disabled by default (default: false)
   --generatedTime                        Generate timestamp at the top of docs.go, disabled by default (default: false)
   --parseDepth value                     Dependency parse depth (default: 100)
   --instanceName value                   This parameter can be used to name different swagger document instances. It is optional.
   --overridesFile value                  File to read global type overrides from. (default: ".swaggo")
   --help, -h                             show help (default: false)
選項 默認值 描述
-g main.go API通用信息所在Go源文件路徑,若是相對路徑則基于API解析目錄。
-d ./ API解析目錄
--exclude 解析掃描時排除的目錄,多個目錄可使用逗號分割。
-p camelcase 結構體字段命名規(guī)則,三種可選snakecase、camelcase、pascalcase。
-o ./docs 文件輸出目錄
--parseVendor 禁用 是否解析vendor目錄中的Go源文件
--parseDependency 禁用 是否解析依賴目錄中的Go源文件
--md - 指定API的描述信息所使用的MarkDown文件所在的目錄
--generateTime 啟用 是否輸出時間到輸出文件docs.go頂部
--cef 禁用 解析包含用于x-codeSamples擴展的代碼示例文件的文件夾
--parseInternal 禁用 解析internal包中的Go文件
--parseDepth 100 依賴解析深度
--instanceName swagger 設置文檔實例名稱

若項目根目錄下存在main.go主入口文件,可直接使用swag init初始化創(chuàng)建docs.go。若接口注釋沒有編寫在默認的main.go主入口文件中,可使用-g標識來告知swag。

例如:

$ swag init -g swag.go

生成文檔

生成Swagger文檔的步驟

  1. 在代碼中添加注釋,先通過注釋的main方法添加整個項目的一般描述。

例如:添加項目級別的文檔

$ vim main.go
package main

import (
    "net/http"
    "github.com/gorilla/mux"
    httpSwagger "github.com/swaggo/http-swagger"
)

// @title RESTful API
// @version 1.0
// @description RESTful API Document
// @host 127.0.0.1:8801
// @BasePath /
func main() {
    router := mux.NewRouter()
    router.PathPrefix("/swagger").Handler(httpSwagger.WrapHandler)
    http.ListenAndServe(":8801", router)
}
  1. 生成swagger配置文件

完成對項目入口函數main()注釋后, 使用swag init命令生成Swagger文檔。

$ swag init -g main.go

執(zhí)行成功后會在項目根目錄下生成docs目錄,并會根據注解生成最新的配置文件。

  1. 加載配置文件

入口文件通過導入httpSwagger "github.com/swaggo/http-swagger"包,即可使用SwaggerUI。使用前必須將swag init生成的文檔配置加載到入口。

$ vim main.go
package main

import (
    "net/http"
    _ "gwf/docs"
    "github.com/gorilla/mux"
    httpSwagger "github.com/swaggo/http-swagger"
)

// @title RESTful API
// @version 1.0
// @description RESTful API Document
// @host 127.0.0.1:8801
// @BasePath /
func main() {
    router := mux.NewRouter()
    router.PathPrefix("/swagger").Handler(httpSwagger.WrapHandler)
    http.ListenAndServe(":8801", router)
}

這里關鍵核心在于導入包的_ "gwf/docs"位置,_是一種導入副作用包的方法,意味著代碼沒有顯式地調用包中的任何方法,但可能執(zhí)行注入注冊處理程序之類的操作。

  1. 運行測試
$ go run main.go

瀏覽器輸入地址 http://127.0.0.1:8801/swagger/index.html ,加載Swagger UI。

SwaggerUI

Swagger提供了在線編輯器,通過復制配置文件內容來顯示UI界面。

通用API信息

主函數采用聲明式注釋格式包含通用API信息

// @title RESTful API
// @version 1.0
// @description RESTful API Document
// @host 127.0.0.1:8801
// @BasePath /
func main() 
  • 若想直接在Swagger中調試API,必須填寫@host@BasePath兩項。
注釋 說明
@title 應用程序名稱,必填。
@version 提供應用程序API的版本
@description 應用程序簡短描述
@tag.name 標簽名稱
@tag.description 標簽描述
@tag.docs.url 標簽的外部文檔URL
@termsOfService API服務條款
@contact.url 聯(lián)系信息的URL,必須采用網址格式。
@license.name 必填,用于API的許可證名稱。
@license.url 用于API許可證的URL,必須采用網址格式。
@host 運行API的主機,主機名或IP地址。
@BasePath 運行API的基本路徑
@accept API可使用的MIME類型列表
@produce API可以生成的MIME類型列表
@query.collection.format 請求URI Query里數組參數的默認格式,默認csv。
@schemes 空格分割的請求的傳輸協(xié)議
@x-name 擴展的鍵,必須以x-開頭,且只能使用JSON值。

處理程序

  • 封裝HTTP服務器,使用gorilla/mux出來路由。
  • 為處理程序添加注釋并通過Swagger測試

創(chuàng)建入口函數

$ vim main.go
package main

import (
    "gwf/router"
    "net/http"
)

// @title RESTful API
// @version 1.0
// @description RESTful API Document
// @host 127.0.0.1:8801
// @BasePath /
func main() {
    http.ListenAndServe(":8801", router.Register())
}

分離路由實現路由注冊

$ vim router/router.go
package router

import (
    "gwf/router/admin"

    "github.com/gorilla/mux"
)

func Register() *mux.Router {
    //創(chuàng)建路由器
    r := mux.NewRouter().StrictSlash(true)
    //注冊路由
    admin.Swag(r)
    admin.Home(r)
    return r
}

創(chuàng)建Swagger服務路由

$ vim router/admin/swag.go
package admin

import (
    _ "gwf/docs"

    "github.com/gorilla/mux"
    httpSwagger "github.com/swaggo/http-swagger"
)

func Swag(r *mux.Router) {
    g := r.PathPrefix("/swag")
    g.Handler(httpSwagger.WrapHandler)
}

創(chuàng)建后臺首頁接口并添加Swagger注釋

$ vim router/admin/home.go
package admin

import (
    "gwf/handler/admin"

    "github.com/gorilla/mux"
)

func Home(r *mux.Router) {
    g := r.PathPrefix("/admin").Subrouter()
    h := admin.NewHome()
    {
        g.HandleFunc("/", h.Index).Methods("GET").Name("admin_home")
    }
}

創(chuàng)建后臺后路由對應的處理程序

$ vim handler/admin/home.go
package admin

import (
    "gwf/response"
    "log"
    "net/http"
)

type home struct{}

func NewHome() *home {
    return new(home)
}

// @Summary 首頁
// @Description 默認首頁
// @Tags 后臺
// @Accept json
// @Produce json
// @Failure 500 {string} string "{code:500, msg:"failure"}"
// @Success 200 {string} string "{code:200, msg:"ok", data:null}"
// @Router /admin [get]
func (*home) Index(w http.ResponseWriter, r *http.Request) {
    log.Printf("%s %s %s\n", r.RemoteAddr, r.RequestURI, r.Method)

    w.Header().Set("Content-Type", "application/json;charset=utf-8")
    w.Write(response.Ok.Json())
}

統(tǒng)一輸出的JSON參數

$ mkdir response && cd response
$ vim response.go
package response

import (
    "encoding/json"
    "log"
)

var (
    Ok  = New(200, "操作成功")
    Err = New(500, "操作失敗")
)

type reply struct {
    Code int         `json:"code"`
    Msg  string      `json:"msg"`
    Data interface{} `json:"data"`
}

// reply 構造函數
func New(code int, msg string) *reply {
    return &reply{
        Code: code,
        Msg:  msg,
        Data: nil,
    }
}

// WithMsg 追加響應消息
func (t *reply) WithMsg(msg string) reply {
    return reply{
        Code: t.Code,
        Msg:  msg,
        Data: t.Data,
    }
}

// WithData 追加響應數據
func (t *reply) WithData(data interface{}) reply {
    return reply{
        Code: t.Code,
        Msg:  t.Msg,
        Data: data,
    }
}

// Json 返回JSON格式的數據
func (t *reply) Json() []byte {
    s := &struct {
        Code int         `json:"code"`
        Msg  string      `json:"msg"`
        Data interface{} `json:"data"`
    }{
        Code: t.Code,
        Msg:  t.Msg,
        Data: t.Data,
    }
    log.Printf("%+v\n", s)
    raw, err := json.Marshal(s)
    if err != nil {
        log.Println(err)
    }
    return raw
}

生成最新Swagger文檔

$ swag init

瀏覽器輸入地址 http://127.0.0.1:8801/swag/index.html 測試接口

測試接口

API操作注釋

// @Summary 首頁
// @Description 默認首頁
// @Tags 后臺
// @Accept json
// @Produce json
// @Failure 500 {string} string "{code:500, msg:"failure"}"
// @Success 200 {string} string "{code:200, msg:"ok", data:null}"
// @Router /admin [get]
func (*home) Index(w http.ResponseWriter, r *http.Request) 
  • @Tags用來給API分組
注釋 描述
@Description 操作行為的詳細說明
@Description.markdown 應用程序的簡短描述,該描述從名為endpointname.md的文件中讀取。
@Id 用于標識操作的唯一字符串,在所有API操作中必須唯一。
@Tags 每個API操作的標簽列表,以逗號分割。
@Summary 操作的簡短摘要
@Accept API可使用的MIME類型列表,Accept僅影響具有請求正文的操作,值必須是"Mime類型"。
@Produce API可以生成的MIME類型的列表,值必須是“Mime類型”。
@Param 空格分隔的參數
@Secuirty API操作的安全性
@Success 空格分割的成功響應
@Failure 空格分割的故障響應
@Response 與@success、@failure作用相同
@Header 空格分割的頭字段
@Router 空格分割的路徑定義
@X-name 擴展字段必須以x-開頭,只能使用JSON值。

@Param

Param參數格式

@Param 參數名 參數類型 參數數據類型 是否必須 參數描述 其它屬性

例如:

@Param id path integer true "自增主鍵"
@Param who query string true "人名"
@Param name body string true "名稱" default(admin)
@Param username formData string true "賬戶" default(admin)
@Param param body main.JSONParam true "上傳的JSON"
參數 示例 描述
參數名 name 解釋參數的名字
參數類型 body 參數類型分為5種
參數數據類型 string 參數數據類型支持類型4類
是否必須 true 該參數是否是必須需要的
參數描述 "名稱" 參數的說明文本
其它屬性 default(admin) 額外屬性,比如枚舉、默認值、值范圍等。

參數類型支持5種

參數類型 描述
path 直接拼接在URL中
query 組合在URL中
formData 一般是POST、PUT方法所用
body Accept為JSON時,使用該字段接受JSON類型。
header 請求頭中傳遞的參數

參數數據類型支持4種

參數數據類型 可選值
string string
integer int、uint、uint32、uint64
number float32
boolean bool

額外屬性可組合使用

額外屬性 描述
Enums(A,B,C) 枚舉值
minlength(1) 最小長度
maxlength(20) 最大長度
minium(1) 最小值
maxinum(20) 最大值
default(0) 默認值

@Success

@Success注釋用于指定成功響應的數據,格式為

@Success HTTP響應碼 {響應參數類型} 響應數據類型 其它描述

例如:

@Success 200 {object} main.File
@Success 200 {string} string ""
元素 描述
HTTP響應碼 諸如200、400、500
響應參數類型 -
響應數據類型 返回的數據類型,可以是自定義類型,也可以是JSON。
其它描述 描述說明

@Router

@Router用于指定路由與HTTP方法,不用添加基礎路徑。

@Router格式如下:

@Router /path/to/handler [HTTP方法]

MIME類型

swag接受所有格式正確的MIME類型,即使匹配*/*,除此之外swag還接受某些MIME類型的別名。

別名 MIME
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
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容