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文檔的步驟
- 在代碼中添加注釋,先通過注釋的
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)
}
- 生成swagger配置文件
完成對項目入口函數main()注釋后, 使用swag init命令生成Swagger文檔。
$ swag init -g main.go
執(zhí)行成功后會在項目根目錄下生成docs目錄,并會根據注解生成最新的配置文件。
- 加載配置文件
入口文件通過導入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í)行注入注冊處理程序之類的操作。
- 運行測試
$ go run main.go
瀏覽器輸入地址 http://127.0.0.1:8801/swagger/index.html ,加載Swagger UI。

Swagger提供了在線編輯器,通過復制配置文件內容來顯示UI界面。
- Swagger在線編輯器 https://editor.swagger.io/
通用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 |