我們們上一次簡單分享了 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
若檢視到如下錯誤列印訊息,原因是沒有安裝swag
的docs
此處可以檢查一下,是否安裝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 | 響應失敗的情況如何處理 @Failure HTTP響應碼 {響應引數型別} 響應資料型別 其他描述 |
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 協議》,轉載必須註明作者和本文連結