Golang使用swaggo自動生成Restful API文檔


#關於Swaggo

相信很多程序猿和我一樣不喜歡寫API文檔。寫代碼多舒服,寫文檔不僅要花費大量的時間,有時候還不能做到面面具全。但API文檔是必不可少的,相信其重要性就不用我說了,一份含糊的文檔甚至能讓前后端人員打起來。 而今天這篇博客介紹的swaggo就是讓你只需要專注於代碼就可以生成完美API文檔的工具。廢話說的有點多,我們直接看文章。

或許你使用過Swagger, 而 swaggo就是代替了你手動編寫yaml的部分。只要通過一個命令就可以將注釋轉換成文檔,這讓我們可以更加專注於代碼。

目前swaggo主要實現了swagger 2.0 的以下部分功能:

  • 基本結構(Basic Structure)

  • API 地址與基本路徑(API Host and Base Path)

  • 路徑與操作 (Paths and Operations)

  • 參數描述(Describing Parameters)

  • 請求參數描述(Describing Request Body)

  • 返回描述(Describing Responses)

  • MIME 類型(MIME Types)

  • 認證(Authentication)

  • Basic Authentication

  • API Keys

  • 添加實例(Adding Examples)

  • 文件上傳(File Upload)

  • 枚舉(Enums)

  • 按標簽分組(Grouping Operations With Tags)

  • 擴展(Swagger Extensions)

下文內容均以gin-swaggo為例

這里是demo地址

2020/05/16 更新:

swag 升級到了 v1.6.5,返回數據格式有更新。

最新的請關注官網文檔

本文最后,優化部分可以了解一下。

#使用使用

#安裝swag-cli-及下載相關包安裝swag cli 及下載相關包

要使用swaggo,首先需要安裝swag cli

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

然后我們還需要兩個包。

    # gin-swagger 中間件
    go get github.com/swaggo/gin-swagger
    # swagger 內置文件
    go get github.com/swaggo/gin-swagger/swaggerFiles

可以看一下自己安裝的版本

    swag --version
    swag version v1.6.5

#在main-go內添加注釋main.go內添加注釋

    package main
    
    import (
    "github.com/gin-gonic/gin"
    	ginSwagger "github.com/swaggo/gin-swagger"
    "github.com/swaggo/gin-swagger/swaggerFiles"
    )
    
    // @title Swagger Example API
    // @version 1.0
    // @description This is a sample server celler server.
    // @termsOfService https://razeen.me
    
    // @contact.name Razeen
    // @contact.url https://razeen.me
    // @contact.email me@razeen.me
    
    // @license.name Apache 2.0
    // @license.url http://www.apache.org/licenses/LICENSE-2.0.html
    
    // @host 127.0.0.1:8080
    // @BasePath /api/v1
    
    func main() {
    
    	r := gin.Default()
        store := sessions.NewCookieStore([]byte("secret"))
    	r.Use(sessions.Sessions("mysession", store))
    
    	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    
    	v1 := r.Group("/api/v1")
    	{
    		v1.GET("/hello", HandleHello)
    		v1.POST("/login", HandleLogin)
    		v1Auth := r.Use(HandleAuth)
    		{
    			v1Auth.POST("/upload", HandleUpload)
    			v1Auth.GET("/list", HandleList)
    		}
    	}
    
    	r.Run(":8080")
    }

如上所示,我們需要導入

    ginSwagger "github.com/swaggo/gin-swagger"
    "github.com/swaggo/gin-swagger/swaggerFiles"

同時,添加注釋。其中:

  • titile: 文檔標題
  • version: 版本
  • description,termsOfService,contact ... 這些都是一些聲明,可不寫。
  • license.name 額,這個是必須的。
  • host,BasePath: 如果你想直接swagger調試API,這兩項需要填寫正確。前者為服務文檔的端口,ip。后者為基礎路徑,像我這里就是“/api/v1”。
  • 在原文檔中還有securityDefinitions.basic,securityDefinitions.apikey等,這些都是用來做認證的,我這里暫不展開。

到這里,我們在mian.go同目錄下執行swag init就可以自動生成文檔,如下:

    ➜  swaggo-gin git:(master) ✗ swag init
    2019/01/12 21:29:14 Generate swagger docs....
    2019/01/12 21:29:14 Generate general API Info
    2019/01/12 21:29:14 create docs.go at  docs/docs.go

然后我們導入這個自動生成的docs包,運行:

    package main
    
    import (
    "github.com/gin-gonic/gin"
    	ginSwagger "github.com/swaggo/gin-swagger"
    "github.com/swaggo/gin-swagger/swaggerFiles"
    
    	_ "github.com/razeencheng/demo-go/swaggo-gin/docs"
    )
    
    // @title Swagger Example API
    // @version 1.0
    // ...
    ➜  swaggo-gin git:(master) ✗ go build
    ➜  swaggo-gin git:(master) ✗ ./swaggo-gin
    [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
    
    [GIN-debug] [WARNING] Running in"debug" mode. Switch to "release" mode in production.
     - using env:   export GIN_MODE=release
     - using code:  gin.SetMode(gin.ReleaseMode)
    
    [GIN-debug] GET    /api/v1/hello             --> main.HandleHello (3 handlers)
    [GIN-debug] POST   /api/v1/login             --> main.HandleLogin (3 handlers)
    [GIN-debug] POST   /upload                   --> main.HandleUpload (4 handlers)
    [GIN-debug] GET    /list                     --> main.HandleList (4 handlers)
    [GIN-debug] GET    /swagger/*any             --> github.com/swaggo/gin-swagger.WrapHandler.func1 (4 handlers)
    [GIN-debug] Listening and serving HTTP on :8080

瀏覽器打開http://127.0.0.1:8080/swagger/index.html, 我們可以看到如下文檔標題已經生成。

#在Handle函數上添加注釋在Handle函數上添加注釋

接下來,我們需要在每個路由處理函數上加上注釋,如:

    // @Summary 測試SayHello
    // @Description 向你說Hello
    // @Tags 測試
    // @Accept mpfd
    // @Produce json
    // @Param who query string true "人名"
    // @Success 200 {string} string "{"msg": "hello Razeen"}"
    // @Failure 400 {string} string "{"msg": "who are you"}"
    // @Router /hello [get]
    funcHandleHello(c *gin.Context) {
    	who := c.Query("who")
    
    if who == "" {
    		c.JSON(http.StatusBadRequest, gin.H{"msg": "who are u?"})
    return
    	}
    
    	c.JSON(http.StatusOK, gin.H{"msg": "hello " + who})
    }

我們再次swag init, 運行一下。

此時,該API的相關描述已經生成了,我們點擊Try it out還可以直接測試該API。

是不是很好用,當然這並沒有結束,這些注釋字段,我們一個個解釋。

這些注釋對應出現在API文檔的位置,我在上圖中已經標出,這里我們主要詳細說說下面參數:

#TagsTags

Tags 是用來給API分組的。

#AcceptAccept

接收的參數類型,支持表單(mpfd) , JSON(json)等,更多如下表。

#ProduceProduce

返回的數據結構,一般都是json

#ParamParam

參數,從前往后分別是:

@Param who query string true “人名”

@Param 1.參數名``2.參數類型``3.參數數據類型``4.是否必須``5.參數描述``6.其他屬性

1.參數名

參數名就是我們解釋參數的名字。

2.參數類型

參數類型主要有四種:

path 該類型參數直接拼接在URL中,如DemoHandleGetFile

    // @Param id path integer true "文件ID"

query 該類型參數一般是組合在URL中的,如DemoHandleHello


    // @Param who query string true "人名"

formData 該類型參數一般是POST,PUT方法所用,如DemoHandleLogin

    // @Param user formData string true "用戶名" default(admin)

bodyAcceptJSON格式時,我們使用該字段指定接收的JSON類型

    // @Param param body main.JSONParams true "需要上傳的JSON"

3.參數數據類型

數據類型主要支持一下幾種:

  • string (string)
  • integer (int, uint, uint32, uint64)
  • number (float32)
  • boolean (bool)

注意,如果你是上傳文件可以使用file, 但參數類型一定是formData, 如下:

    // @Param file formData file true "文件"

4.是否是必須

表明該參數是否是必須需要的,必須的在文檔中會黑體標出,測試時必須填寫。

5.參數描述

就是參數的一些說明

6.其他屬性

除了上面這些屬性外,我們還可以為該參數填寫一些額外的屬性,如枚舉,默認值,值范圍等。如下:

    枚舉
    // @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" mininum(1) maxinum(10)
    
    設置默認值
    // @Param default query string false "string default" default(A)
    

而且這些參數是可以組合使用的,如:

    // @Param enumstring query string false "string enums" Enums(A, B, C) default(A)
#SuccessSuccess

指定成功響應的數據。格式為:

// @Success 1.HTTP響應碼``{2.響應參數類型}``3.響應數據類型``4.其他描述

1.HTTP響應碼

也就是200,400,500那些。

2.響應參數類型 / 3.響應數據類型

返回的數據類型,可以是自定義類型,可以是json。

  • 自定義類型

在平常的使用中,我都會返回一些指定的模型序列化JSON的數據,這時,就可以這么

    // @Success 200 {object} main.File

其中,模型直接用包名.模型即可。你會說,假如我返回模型數組怎么辦?這時你可以這么寫:

    // @Success 200 {anrry} main.File

將如你只是返回其他的數據格式可如下寫:

    // @Success 200 {string} string ""

4.其他描述

可以添加一些說明。

#FailureFailure

​ 同Success。

#RouterRouter

​ 指定路由與HTTP方法。格式為:

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

​ 不用加基礎路徑哦。

#生成文檔與測試生成文檔與測試

其實上面已經穿插的介紹了。

main.go下運行swag init即可生成和更新文檔。

點擊文檔中的Try it out即可測試。 如果部分API需要登陸,可以Try登陸接口即可。

#優化優化

看到這里,基本可以使用了。但文檔一般只是我們測試的時候需要,當我的產品上線后,接口文檔是不應該給用戶的,而且帶有接口文檔的包也會大很多(swaggo是直接build到二進制里的)。

想要處理這種情況,我們可以在編譯的時候優化一下,如利用build tag來控制是否編譯文檔。

main.go聲明swagHandler,並在該參數不為空時才加入路由:


    package main
    
    //...
    
    var swagHandler gin.HandlerFunc
    
    funcmain(){
    // ...
    
    if swagHandler != nil {
    			r.GET("/swagger/*any", swagHandler)
            }
    
    //...
    }
    

同時,我們將該參數在另外加了build tag的包中初始化。

  
    // +build doc
    
    package main
    
    import (
    	_ "github.com/razeencheng/demo-go/swaggo-gin/docs"
    
    	ginSwagger "github.com/swaggo/gin-swagger"
    "github.com/swaggo/gin-swagger/swaggerFiles"
    )
    
    funcinit() {
    	swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler)
    }

之后我們就可以使用go build -tags "doc"來打包帶文檔的包,直接go build來打包不帶文檔的包。

你會發現,即使我這么小的Demo,編譯后的大小也要相差19M !

    ➜  swaggo-gin git:(master) ✗ go build
    ➜  swaggo-gin git:(master) ✗ ll swaggo-gin
    -rwxr-xr-x  1 xxx  staff    15M Jan 13 00:23 swaggo-gin
    ➜  swaggo-gin git:(master) ✗ go build -tags "doc"
    ➜  swaggo-gin git:(master) ✗ ll swaggo-gin
    -rwxr-xr-x  1 xxx  staff    34M Jan 13 00:24 swaggo-gin
    

文章到這里也就結束了,完整的Demo地址在這里

本文章摘自https://razeencheng.com/post/go-swagger.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM