工作中後端是如何將API提供出去的?swaggo很不錯

小魔童哪吒發表於2021-08-14

我們們上一次簡單分享了 GO 許可權管理之 Casbin ,他一般指根據系統設定的安全規則或者安全策略

  • 分享了許可權管理是什麼
  • Casbin 是什麼
  • Casbin 的特性
  • Casbin 的應用案例

要是感興趣的話,我們們以後可以多多深入的探討和分享,歡迎檢視文章 GO 許可權管理之 Casbin

今天我們們來分享一下我們們在工作中,後端的小夥伴是如何將 API 高效的提供出去的呢?

API 由一組定義和協議組合而成,可用於構建和企業整合應用軟體

API 就是 應用程式設計介面

相信有很多朋友喜歡寫文件的,可能會使用markdown將介面寫下來,相關負責人約定好一個固定的模板

有的會使用簡單的文字檔案,有的大兄弟可能連一點文件資料都不輸出,這樣在電視劇裡面是活不過第二集的

那麼測試的時候呢?

一般會使用postman工具,對照著介面進行引數的設定,進行自測,或者寫指令碼進行測試

可是,這樣都太麻煩了,還要畫太多的時間在書寫介面上面,每次修改介面還要對應的修改文件,相當繁瑣,有點反人性

那我們們來看看 GO swaggo工具 是如何解決上述問題的,都有哪些騷操作吧

swaggo 是什麼?

是一個工具,專門用於將 golang 註解自動轉換為Swagger 2.0文件

Swagger 又是個啥?

Swagger 是一個Web 服務

他是一個規範且完整的框架,可以生成、描述、呼叫和視覺化 RESTful 風格的文件

那麼他的優勢是個啥?

大致有如下 2 個優勢:

  • 支援 API 自動生成同步的線上文件

使用 Swagger 後可以直接通過程式碼生成文件,不再需要自己手動編寫介面文件了

  • 提供了 Web 頁面線上測試 API

Swagger 生成的文件還支援線上測試

引數和格式都定好了,直接在介面上輸入引數對應的值即可線上測試介面,用起來真的別提多香了

我們們如何使用 swaggo?

我們們來寫一個最基本你的swaggo的案例使用,大致分為如下步驟:

  • 安裝swag,用於自動生成文件
  go get -u github.com/swaggo/swag/cmd/swag
  • 需要使用到如下 2 個包, 可以先知悉一下,我們們還是預設是用go mod 的方式,寫完程式碼之後 直接go build ,會將用到的包都拉下來

第一個是 gin-swagger , 我們們用gin 來玩 swagger 比較方便,之前也和大家分享過gin 的使用,感興趣的可以檢視文章 Gin實戰演練

go get github.com/swaggo/gin-swagger

第二個是swagger 內建檔案

go get github.com/swaggo/gin-swagger/swaggerFiles
  • 需要簡單使用 gin 框架

我們們開始編碼一個簡單的小DEMO

package main

import (
   "github.com/gin-gonic/gin"
   ginSwagger "github.com/swaggo/gin-swagger"
   "github.com/swaggo/gin-swagger/swaggerFiles"
   "net/http"
   _ "myswa/docs"
)

// gin 的處理函式  Hello
func Hello(c *gin.Context) {

   c.JSON(http.StatusOK, gin.H{"msg": "hello wrold xiaomotong" })
}

func main() {

   r := gin.Default()

   r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

   // 路由分組, 第一個版本的api  v1
   v1 := r.Group("/api/v1")
   {
      v1.GET("/hello", Hello)

   }

   // 監聽埠為 8888
   r.Run(":8888")
}

上述程式碼大致分為這幾步:

  • 使用 r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) 將 swaggerFiles.Handler 註冊上
  • 寫一個自定義的路由和對應的方法
  • 監聽指定的地址和埠

上述程式碼編寫完畢之後,我們們可以在和main.go 的同級目錄中初始化一個 go的模組,再go build我們們執行程式

go mod init myswa
go build

上述命令 go mod init myswa,初始化模組為 myswa ,以後匯入我們們的本地包路徑都需要是以myswa開頭

執行上述命令後,會初始化一個myswa的模組,執行go build 後,會將用到的相關包拉下來,進行編譯

編譯成功後在瀏覽器中鍵入:

http://127.0.0.1:8888/swagger/index.html

若檢視到如下錯誤列印訊息,原因是沒有安裝swagdocs

此處可以檢查一下,是否安裝swag 成功

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

安裝成功後,可以使用 swag init 進行初始化,swag 會幫我們生成相應的docs,例如我的程式碼目錄是這個樣子的

這也就是為什麼我們們匯入的包中有一個是 _ "myswa/docs"

再次在瀏覽器中鍵入:

http://127.0.0.1:8888/swagger/index.html,可以檢視到如下效果,則為成功

新增註釋

我們們在main.go檔案中,加入點註釋,再看看效果,例如

package main

import (
    "github.com/gin-gonic/gin"
    ginSwagger "github.com/swaggo/gin-swagger"
    "github.com/swaggo/gin-swagger/swaggerFiles"
    "net/http"
    _ "myswa/docs"
)

// gin 的處理函式  Hello
func Hello(c *gin.Context) {

    c.JSON(http.StatusOK, gin.H{"msg": "hello wrold xiaomotong" })
}
// @title Xiaomotong Swagger  API
// @version 1.0
// @description 參加更文挑戰第 26 天了,主題是 Swagger
// @termsOfService https://juejin.cn/user/3465271329953806

// @contact.name https://juejin.cn/user/3465271329953806
// @contact.url https://juejin.cn/user/3465271329953806
// @contact.email xxx@xxx.com.cn


// @host 127.0.0.1:8888
// @BasePath /api/v1
func main() {

    r := gin.Default()

    r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

    // 路由分組, 第一個版本的api  v1
    v1 := r.Group("/api/v1")
    {
        v1.GET("/hello", Hello)

    }

    // 監聽埠為 8888
    r.Run(":8888")
}

新增完註釋後執行如下 3 步:

  • 刪除掉 之前生成的 docs 目錄
  • 再次在main.go同級目錄下執行 swag init 生成最新的文件
  • 執行 go run main.go , 瀏覽器訪問http://127.0.0.1:8888/swagger/index.html我們們就可以看到如下效果

此時檢視我們們生成的docs目錄下看看具體檔案內容都有個啥?

這些都是自動生成的

my_swa/docs/swagger.json 如下

{
    "swagger": "2.0",
    "info": {
        "description": "參加更文挑戰第 26 天了,主題是 Swagger",
        "title": "Xiaomotong Swagger  API",
        "termsOfService": "https://juejin.cn/user/3465271329953806",
        "contact": {
            "name": "https://juejin.cn/user/3465271329953806",
            "url": "https://juejin.cn/user/3465271329953806",
            "email": "xxx@xxx.com.cn"
        },
        "version": "1.0"
    },
    "host": "127.0.0.1:8888",
    "basePath": "/api/v1",
    "paths": {}
}

my_swa/docs/swagger.yaml如下:

basePath: /api/v1
host: 127.0.0.1:8888
info:
  contact:
    email: xxx@xxx.com.cn
    name: https://juejin.cn/user/3465271329953806
    url: https://juejin.cn/user/3465271329953806
  description: 參加更文挑戰第 26 天了,主題是 Swagger
  termsOfService: https://juejin.cn/user/3465271329953806
  title: Xiaomotong Swagger  API
  version: "1.0"
paths: {}
swagger: "2.0"

實際UI顯示的資料來源於上述 兩個檔案

對於上述註釋中的關鍵字,我們們列一個表格瞅瞅

tag 說明
titile 文件標題
version 版本
description 描述,可寫可不寫
host 服務文件的埠
BasePath 基礎路徑
Summary 總結
Description 描述
Tags 用來給API分組
Accept 接收的引數型別,支援表單(mpfd) 和 JSON(json)
Param 引數,具體的寫法如下:
@Param 引數名 引數型別 引數資料型別 是否必須 引數描述 其他屬性
引數的型別
- path 這個型別的值可以直接拼接到 URL上面
@Param name path string true “具體名字”- query 這個型別值 一般是 和 URL 進行組合

- query 這個型別值 一般是 和 URL 進行組合
@Param name query string true “具體名字”

- formData 這個型別的值 一般是用於 POST 方法,或者 PUT方法
@Param name formData string true “具體名字” default(root)

引數的資料型別有如下幾種
string(string) , integer (int, uint, uint32, uint64) , number (float32) , boolean (bool) , file 用於上傳檔案

其他屬性支援**:
- 列舉
- 值的新增範圍
- 設定預設值
Success 響應成功的情況如何處理
@Success HTTP響應碼 {響應引數型別} 響應資料型別 其他描述
Failure 響應失敗的情況如何處理
@FailureHTTP響應碼 {響應引數型別} 響應資料型別 其他描述
Router 路由 , 不加基礎路徑的
@Router /hello [get]

我們給函式新增上對應的註釋,看看效果

// @Summary hello world
// @Description 對誰說 hello wrold
// @Tags 挑戰測試
// @Accept json
// @Param name query string true "具體名字"
// @Success 200 {string} string "{"msg": "hello xxx"}"
// @Failure 400 {string} string "{"msg": "NO name"}"
// @Router /hello [get]
// gin 的處理函式  Hello
func Hello(c *gin.Context) {
   name := c.Query("name")
   c.JSON(http.StatusOK, gin.H{"msg": "hello wrold" + name})
}

新增完註釋後執行如下 3 步:

  • 刪除掉 之前生成的 docs 目錄
  • 再次在main.go同級目錄下執行 swag init 生成最新的文件
  • 執行 go run main.go , 瀏覽器訪問http://127.0.0.1:8888/swagger/index.html我們們就可以看到如下效果

我們們在頁面上做一下基本測試,填入name ,執行,看看效果

吶,測試成功

如果將這樣的文件給出去,對於前端來說就非常的友好了,並且對於我們的工作量沒有什麼增加,寫程式碼的時候,順便把註釋寫上去

釋出

開發完畢後,釋出版本的時候,不可能還要帶上自己的api文件吧,這是不應該的

因此,我們們可以通過 build tag 的方式來控制是否編譯文件,這裡留個懸念,感興趣的朋友可以嘗試一下

感興趣的朋友,可以將上述程式碼貼到本地,安裝對應的庫,執行一下,看看效果,確實非常好用,希望能幫助到你

總結

  • swaggo 是什麼
  • swagger 是什麼
  • 如何使用 swaggo
  • 如何測試 swaggo

歡迎點贊,關注,收藏

朋友們,你的支援和鼓勵,是我堅持分享,提高質量的動力

好了,本次就到這裡,下一次 GO 的定時器 timer 和定時任務cron

技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。

我是小魔童哪吒,歡迎點贊關注收藏,下次見~

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章