Go学习笔记(六) | 使用swaggo自动生成Restful

2019-11-05  本文已影响0人  袁俊亮技术博客

Go学习笔记(五) 使用swaggo自动生成Restful API文档

Desc: 使用gin-swagger快捷生成Restful API文档,gin-swagger,swaggo,Restful API文档,gin

相信很多程序猿和我一样不喜欢写API文档。写代码多舒服,写文档不仅要花费大量的时间,有时候还不能做到面面具全。但API文档是必不可少的,相信其重要性就不用我说了,一份含糊的文档甚至能让前后端人员打起来。 而今天这篇博客介绍的swaggo就是让你只需要专注于代码就可以生成完美API文档的工具。废话说的有点多,我们直接看文章。

大概最后文档效果是这样的:

image.png

关于Swaggo

或许你使用过Swagger, 而 swaggo就是代替了你手动编写yaml的部分。只要通过一个命令就可以将注释转换成文档,这让我们可以更加专注于代码。

目前swaggo主要实现了swagger 2.0 的以下部分功能:

下文内容均以gin-swaggo为例

这里是demo地址

使用

安装swag cli 及下载相关包

要使用swaggo,首先需要安装swag cli

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

然后我们还需要两个包。

# gin-swagger 中间件
$ go get github.com/swaggo/gin-swagger
# swagger 内置文件
$ go get github.com/swaggo/gin-swagger/swaggerFiles

main.go内添加注释

package main

import (
    "github.com/gin-gonic/gin"
    ginSwagger "github.com/swaggo/gin-swagger"
    "github.com/swaggo/gin-swagger/swaggerFiles"
)

// @title Swagger Example API
// @version 1.0
// @description This is a sample server celler server.
// @termsOfService https://razeen.me

// @contact.name Razeen
// @contact.url https://razeen.me
// @contact.email me@razeen.me

// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host 127.0.0.1:8080
// @BasePath /api/v1

func main() {

    r := gin.Default()
    store := sessions.NewCookieStore([]byte("secret"))
    r.Use(sessions.Sessions("mysession", store))

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

    v1 := r.Group("/api/v1")
    {
        v1.GET("/hello", HandleHello)
        v1.POST("/login", HandleLogin)
        v1Auth := r.Use(HandleAuth)
        {
            v1Auth.POST("/upload", HandleUpload)
            v1Auth.GET("/list", HandleList)
        }
    }

    r.Run(":8080")
}

如上所示,我们需要导入

ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"

同时,添加注释。其中:

到这里,我们在mian.go同目录下执行swag init就可以自动生成文档,如下:

➜  swaggo-gin git:(master) ✗ swag init
2019/01/12 21:29:14 Generate swagger docs....
2019/01/12 21:29:14 Generate general API Info
2019/01/12 21:29:14 create docs.go at  docs/docs.go

然后我们导入这个自动生成的docs包,运行:

package main

import (
    "github.com/gin-gonic/gin"
    ginSwagger "github.com/swaggo/gin-swagger"
    "github.com/swaggo/gin-swagger/swaggerFiles"

    _ "github.com/razeencheng/demo-go/swaggo-gin/docs"
)

// @title Swagger Example API
// @version 1.0
// ...
➜  swaggo-gin git:(master) ✗ go build
➜  swaggo-gin git:(master) ✗ ./swaggo-gin
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /api/v1/hello             --> main.HandleHello (3 handlers)
[GIN-debug] POST   /api/v1/login             --> main.HandleLogin (3 handlers)
[GIN-debug] POST   /upload                   --> main.HandleUpload (4 handlers)
[GIN-debug] GET    /list                     --> main.HandleList (4 handlers)
[GIN-debug] GET    /swagger/*any             --> github.com/swaggo/gin-swagger.WrapHandler.func1 (4 handlers)
[GIN-debug] Listening and serving HTTP on :8080

浏览器打开http://127.0.0.1:8080/swagger/index.html, 我们可以看到如下文档标题已经生成。

image.png

在Handle函数上添加注释

接下来,我们需要在每个路由处理函数上加上注释,如:

// @Summary 测试SayHello
// @Description 向你说Hello
// @Tags 测试
// @Accept mpfd
// @Produce json
// @Param who query string true "人名"
// @Success 200 {string} json "{"msg": "hello Razeen"}"
// @Failure 400 {string} json "{"msg": "who are you"}"
// @Router /hello [get]
func HandleHello(c *gin.Context) {
    who := c.Query("who")

    if who == "" {
        c.JSON(http.StatusBadRequest, gin.H{"msg": "who are u?"})
        return
    }

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

我们再次swag init, 运行一下。

image.png

此时,该API的相关描述已经生成了,我们点击Try it out还可以直接测试该API。

image.png

是不是很好用,当然这并没有结束,这些注释字段,我们一个个解释。

image.png

这些注释对应出现在API文档的位置,我在上图中已经标出,这里我们主要详细说说下面参数:

Tags

Tags 是用来给API分组的。

Accept

接收的参数类型,支持表单(mpfd) 和 JSON(json)

Produce

返回的数据结构,一般都是json, 其他支持如下表:

Mime Type 声明
application/json json
text/xml xml
text/plain plain
html html
multipart/form-data mpfd
application/x-www-form-urlencoded x-www-form-urlencoded
application/vnd.api+json json-api
application/x-json-stream json-stream
application/octet-stream octet-stream
image/png png
image/jpeg jpeg
image/gif gif
Param

参数,从前往后分别是:

@Param 1.参数名 2.参数类型 3.参数数据类型 4.是否必须 5.参数描述 6.其他属性

Success

指定成功响应的数据。格式为:

// @Success 1.HTTP响应码 {2.响应参数类型} 3.响应数据类型 4.其他描述

Failure

​ 同Success。

Router

​ 指定路由与HTTP方法。格式为:

// @Router /path/to/handle [HTTP方法]

​ 不用加基础路径哦。

生成文档与测试

其实上面已经穿插的介绍了。

main.go下运行swag init即可生成和更新文档。

点击文档中的Try it out即可测试。 如果部分API需要登陆,可以Try登陆接口即可。

优化

看到这里,基本可以使用了。但文档一般只是我们测试的时候需要,当我的产品上线后,接口文档是不应该给用户的,而且带有接口文档的包也会大很多(swaggo是直接build到二进制里的)。

想要处理这种情况,我们可以在编译的时候优化一下,如利用build tag来控制是否编译文档。

main.go声明swagHandler,并在该参数不为空时才加入路由:

package main

//...

var swagHandler gin.HandlerFunc

func main(){
    // ...
    
        if swagHandler != nil {
            r.GET("/swagger/*any", swagHandler)
        }
    
    //...
}

同时,我们将该参数在另外加了build tag的包中初始化。

// +build doc

package main

import (
    _ "github.com/razeencheng/demo-go/swaggo-gin/docs"

    ginSwagger "github.com/swaggo/gin-swagger"
    "github.com/swaggo/gin-swagger/swaggerFiles"
)

func init() {
    swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler)
}

之后我们就可以使用go build -tags "doc"来打包带文档的包,直接go build来打包不带文档的包。

你会发现,即使我这么小的Demo,编译后的大小也要相差19M !

➜  swaggo-gin git:(master) ✗ go build
➜  swaggo-gin git:(master) ✗ ll swaggo-gin
-rwxr-xr-x  1 xxx  staff    15M Jan 13 00:23 swaggo-gin
➜  swaggo-gin git:(master) ✗ go build -tags "doc"
➜  swaggo-gin git:(master) ✗ ll swaggo-gin
-rwxr-xr-x  1 xxx  staff    34M Jan 13 00:24 swaggo-gin

文章到这里也就结束了,完整的Demo地址在这里

相关链接

原文地址:

上一篇 下一篇

猜你喜欢

热点阅读