Java使用Spring Boot寫Restful API時,可以在代碼里用注解來標識API,編譯為Jar包后,運行時Web應用可以直接托管API文檔。具體的可以參考這篇文章:使用swagger來做API文檔。
那么golang系有沒有類似的做法呢?
有是有的,只是沒有springfox的那么方便就是了。
swaggo提供了golang版本的swagger自動生產Restful API文檔,其做法是在代碼中按swaggo的格式寫作api的注釋,然后swaggo會去解析這些注釋,生成swagger的文檔以及托管到web的框架代碼(主要是init()函數),最終將代碼編譯到web應用中,達到api文檔托管的目的。
由於我的Restful框架用的是gin,所以下面以gin-swagger為例,說明swaggo的用法。
安裝swag命令行
要使用swaggo,首先要下載一個swag命令行。
go get github.com/swaggo/swag/cmd/swag
在$GOPATH/bin/下會看到多了一個swag。把$GOPATH/bin/加到PATH后,就可以直接用swag
命令行了。
在包含main.go
的Go工程的根目錄下執行swag init
,swag會檢索當前工程里的swag注釋(類似上述Java中的注解),生成docs.go
以及swagger.json/yaml
。
獲取gin專用的gin-swagger
里面包含了一個示例代碼。
$ go get -u github.com/swaggo/gin-swagger $ go get -u github.com/swaggo/gin-swagger/swaggerFiles
編寫gin-swagger需要的注釋
接下來就是編寫注釋了。注釋分為兩部分,一是整體應用的說明,二是具體api的說明。
整體應用的說明
在主入口main.go中增加:
import "github.com/swaggo/gin-swagger" // gin-swagger middleware import "github.com/swaggo/gin-swagger/swaggerFiles" // swagger embed files
以及針對該應用程序的api說明。
package main import ( "github.com/gin-gonic/gin" "github.com/swaggo/gin-swagger" "github.com/swaggo/gin-swagger/swaggerFiles" _ "github.com/swaggo/gin-swagger/example/docs" ) // @title Swagger Example API // @version 0.0.1 // @description This is a sample server Petstore server. // @BasePath /api/v1/ func main() { r := gin.New() r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) r.Run() }
注意@BasePath
。托管在web應用的目的,是可以在瀏覽器打開的swagger ui中直接執行restful請求,而不必要使用postman這種restful client。那么swagger ui發送api請求時,url是根據誰來定的呢?就是swagger注釋中說明的@BasePath
、@Router
,而不是gin代碼中聲明的路徑(沒那么智能)。
具體api的說明
// // @Summary Add a new pet to the store // @Description get string by ID // @Accept json // @Produce json // @Param some_id path int true "Some ID" // @Success 200 {string} string "ok" // @Failure 400 {object} web.APIError "We need ID!!" // @Failure 404 {object} web.APIError "Can not find ID" // @Router /testapi/get-string-by-int/{some_id} [get] func GetStringByInt(c *gin.Context) { err := web.APIError{} fmt.Println(err) }
說明下幾個參數。
@Param指的是用戶請求的參數,可以是url路徑(path)、query、body。如果不需要參數(例如get all類型的,由url就齊活了),則不需要加@Param。參數可以是 int 或者 string 類型。這里的定義會影響swagger ui發送的請求,如果定義錯了會導致發送請求的數據不對,例如對數字進行了轉義。
// @Param group body model.SwagGroupAdd true "Add group" // @Param name path string true "Group Name" // @Param role query int true "Role ID"
@Success和@Failure定義了返回值,類型可以是 string、object、array。按照一般的restful定義,這三個類型足夠表達返回值了。
GET /collection:返回資源對象的列表(數組) GET /collection/resource:返回單個資源對象 POST /collection:返回新生成的資源對象 PUT /collection/resource:返回完整的資源對象 PATCH /collection/resource:返回完整的資源對象 DELETE /collection/resource:返回一個空文檔
不過有些不太標准的restful實踐會在上述返回之上再包裝一個code/message/body,所以對swaggo來說會造成一些新的負擔,因為必須為這些返回類型單獨加對應的類型。不太推薦這么做。
swag init
在項目根目錄里執行swag init
,生成docs/docs.go
;再執行go run main.go
,訪問http://localhost:8080/swagger/index.html
,就可以愉快的使用swagger ui了。
來源:https://ieevee.com/tech/2018/04/19/go-swag.html