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了。

swagger-ui