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