乐趣区

关于后端:超高效SwaggerYapi的秘密

导读 :置信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端常常埋怨后端给的接口文档与理论状况不统一。后端又感觉编写及保护接口文档会消耗不少精力,常常来不及更新。其实无论是前端调用后端,还是后端调用后端,都冀望有一个好的接口文档。然而随着时间推移,版本迭代,接口文档往往很容易就跟不上代码了, 更会呈现之前的同学没有把接口文档交接分明就到职,留下一个沉重简单的我的项目,从新啃起来异样艰巨,不亚于本人从头写一遍。因而仅仅只通过强制来标准大家是不够的。咱们钻研了 Swagger 到 Yapi 的买通办法。
有了它之后,咱们能够做到每次写完代码,只须要顺便批改正文,而后提交,Yapi 上就能主动更改咱们的接口文档。

全文 8199 字,预计浏览工夫 21 分钟。

一、Swagger 简介

Swagger 是一个标准和残缺的框架,用于生成、形容、调用和可视化 RESTful 格调 Web 服务。你只须要依照它的标准去定义接口及接口相干的信息。再通过 Swagger 衍生进去的一系列我的项目和工具,就能够做到生成各种格局的接口文档,生成多种语言的客户端和服务端的代码,以及在线接口调试页面等等。

这样,如果依照新的开发模式,在开发新版本或者迭代版本的时候,只须要更新 Swagger 形容文件,就能够主动生成接口文档和客户端服务端代码,做到调用端代码、服务端代码以及接口文档的一致性。

二、Swagger 搭建

以下步骤建设在曾经有可能胜利运行 go 的环境上。

在 go-swagger 官网教程上能看到最全的教程,有能力的能够间接走官网教程。

2.1►装置

下面的所有下载方式都可行,然而为了兼容咱们的所有状况,所以抉择这种,间接下载代码。

把命令精简一下,其实就干了两件事:

1、clone go-swagger 的代码;

2、把 swaager 加进 GOROOT。

mkdir DownLoad
cd DownLoad
git clone https://github.com/go-swagger/go-swagger
cd DownLoad/go-swagger-master/cmd/swagger/
go install .

验证一下是否胜利:

[work@hangchuang /]$ swagger -h
Usage:
  swagger [OPTIONS] <command>

Swagger tries to support you as best as possible when building APIs.

It aims to represent the contract of your API with a language agnostic description of your application in json or yaml.


Application Options:
  -q, --quiet                  silence logs
      --log-output=LOG-FILE    redirect logs to file

Help Options:
  -h, --help                   Show this help message

Available commands:
  diff      diff swagger documents
  expand    expand $ref fields in a swagger spec
  flatten   flattens a swagger document
  generate  generate go code
  init      initialize a spec document
  mixin     merge swagger documents
  serve     serve spec and docs
  validate  validate the swagger document
  version   print the version

2.2►搭建

  • 这一部分全部都是对于 swagger 的用法的,先来个最简略的, 接口正文,把样例下面的正文放复制到接口上方:

  • 样例文档正文:

  • 运行 swagger,生成接口文档

    命令:swagger generate spec -o ./swagger.json

  • 启动 swagger 服务,进入接口文档页面

    命令:swagger serve –no-open swagger.json

三、Swagger 标准

Swagger 正文的标准以及用法如下。

3.1►swagger:meta

简介:swagger:meta 是你的所有的 API 的概要,咱们用它来造成咱们的 API 文档的结尾介绍。

// Go-Swagger API.(title)
//
// 这是咱们的测试 API (description)
//
//      Terms Of Service:
//     there are no TOS at this moment, use at your own risk we take no responsibility
//
//     Schemes: http, https
//     Host: localhost
//     BasePath: /go-swagger/test
//     Version: 0.0.1
//     License: MIT http://opensource.org/licenses/MIT
//     Contact: Zhubangzheng<zhubangzheng@baidu.com> zhubangzheng@baidu.com
//
//     Consumes:
//     - application/json
//     - application/xml
//
//     Produces:
//     - application/json
//     - application/xml
//
//     Security:
//     - api_key:
//
//     SecurityDefinitions:
//     api_key:
//          type: apiKey
//          name: KEY
//          in: header
//     oauth2:
//         type: oauth2
//         authorizationUrl: /oauth2/auth
//         tokenUrl: /oauth2/token
//         in: header
//         scopes:
//           bar: foo
//         flow: accessCode
//
//     Extensions:
//     x-meta-value: value
//     x-meta-array:
//       - value1
//       - value2
//     x-meta-array-obj:
//       - name: obj
//         value: field
//
// swagger:meta
package test

留神:正文的结尾 swagger:meta 和 package 之间不能有空行,否则无奈被 swagger 辨认。

注解用法:

3.2►swagger:route

swagger:route 是最次要的一个正文参数,是你的单个 API 接口的详细信息。

格局:swagger:route [method] [path pattern] [tag1 tag2 tag3] [operation id]

[method]和 [path pattern]必选,前面的 [tag] 依据你本人决定,首先是你以后接口的 tag,而后再思考加上其余。最初的 [operation id] 是你的办法的惟一标识,如果仅是作为一个接口文档能够不填,然而它在很多中央都被用作办法名。例如用于客户端生成的办法。

 // ServeAPI serves the API for this record store
func ServeAPI(host, basePath string, schemes []string) error {// swagger:route GET /{id}/checkout SwaggerTest swagger_test_checkout
  //
  // Swagger 测试接口
  //
  // 用于 Swagger 测试
  //
  //     Consumes:
  //     - application/json
  //     - application/x-protobuf
  //
  //     Produces:
  //     - application/json
  //     - application/x-protobuf
  //
  //     Schemes: http, https, ws, wss
  //
  //     Deprecated: true
  //
  //     Security:
  //       api_key:
  //       oauth: read, write
  //
  //     Responses:
  //       default: genericError
  //       200: someResponse
  //       422: validationError
    mountItem("GET", basePath+"/{id}/checkout", nil)
}

Response 和前面定义的 swagger:response 对应。

3.3►swagger:patameters

swagger:parameters 是接口的参数正文

格局 :swagger:parameters [operationid1 operationid2],parameters 通过[operation id] 和 route 绑定。

参数的玩法很多,然而根本都用不上具体能够在官网文档查看 swagger:parameters。

因为咱们次要应用 GET、POST,而官网只介绍了 GET 办法,内网外网对于 swagger:parameters 注解的 POST 的用法介绍甚少,因而在这里介绍 GET 和 POST 的次要玩法即可。

// swagger:parameters swagger_test_checkout 
type SwaggerTest struct {// SwaggerTest 接口测试参数 1 (description)
  // required: true(是否必须)
  // in: query(参数所在的地位)
    ID uinat64 `json:"id"`
}

重点:GET 办法的 in 正文 可接 query、header、cookie、path,不同状况自定。

以上就是咱们申明一个 GET 的参数的必要正文,其余都是非必要,如下图,能够依据本人的具体情况增加。

  • POST:
// swagger:parameters swagger_test_checkout 
type SwaggerTest struct {// SwaggerTest 接口测试参数 1 (description)
  // required: true(是否必须)
  // in: formData(参数所在的地位)
    ID uinat64 `json:"id"`
}

POST 办法,参数的地位不在 body,换句话说不能 in:body,而是要应用 in:formData,这样的格局导入到 yapi 之后才会呈现在 body 里,且在本地的 swagger ui 中也才会正确显示。还有一点须要留神就是倡议把 swagger:route 处的 Consumes 设置成 multipart/form-data,即:

  // ServeAPI serves the API for this record store
func ServeAPI(host, basePath string, schemes []string) error {// swagger:route GET /{id}/checkout SwaggerTest swagger_test_checkout
  //
  // Swagger 测试接口
  //
  // 用于 Swagger 测试
  //
  //     Consumes:
  //     multipart/form-data
  //
  //     ......
    mountItem("GET", basePath+"/{id}/checkout", nil)
}

格局 :swagger:response [response name],response 通过[response name] 和 route 处定义的 response 绑定。

响应正文和参数的用法根本一样 swagger:response,这里不须要赘述,间接举例。

// A ValidationError is an error that is used when the required input fails validation.
// swagger:response validationError
type ValidationError struct {
    // The error message
    // in: body
    Body struct {
        // The validation message
        //
        // Required: true
        // Example: Expected type int
        Message string
        // An optional field name to which this validation applies
        FieldName string
    }
}

重点:以上的用法是 response 的根底用法,然而实际上并不合乎很多公司外部的构造定义,所以上面会讲真正的灵便且实用的用法。

1、swagger:response 能够呈现在任意构造体上。 不须要专门找到咱们的 response 层,或者甚至没有 response 层的,而是每一个接口都定义了一个专门的 response,最初再对立用 interface 解决,从而导致咱们在历史我的项目里加上 swagger 异样艰难。

例如:

// SwaggerTestResponse
// swagger:response test_res
type SwaggerTestResponse struct {
    // The error message
    // in: body
    Body struct {
        // The validation message
        //
        // Required: true
        // Example: Expected type int
        Message string
        // An optional field name to which this validation applies
        FieldName string
    }
}

留神::必须严格依照格局,Response 构造体下嵌套一个 Body 构造体,也就是说如果是咱们的历史我的项目,就得在 Response 外再包一层。例如:这是一正在是用的我的项目的 Response 返回,咱们在上方加上 swagger:response,前面跟上它的惟一 id,test,在接口的返回处应用。

// Test
// swagger:response old_api_resp
type OldAPIRes struct {
   // Test
   // in: body
   ID uint64
   Name string
   Time string
}
  // ServeAPI serves the API for this record store
func ServeAPI(host, basePath string, schemes []string) error {// swagger:route GET /{id}/checkout SwaggerTest swagger_test_checkout
  //
  // Swagger 测试接口
  //
  // 用于 Swagger 测试
  //
  //     Consumes:
  //     - multipart/form-data
  //     Schemes: http
  //     Responses:
  //       200: old_api_resp
    mountItem("GET", basePath+"/{id}/checkout", nil)
}

而后咱们生成 swagger.json,发现所有参数都被定义在了 header 下,而这些返回参数实际上应该位于 body 中,否则就无奈被 swagger ui 和 yapi 辨认。

换句话说 swagger 的 in:body 只辨认构造体内嵌套的构造体,为了投合 swagger 的辨认要求,咱们对构造进行革新,换成上面这种写法,就能够被辨认在 body 里了。

// Test
// swagger:response old_api_resp
type OldAPIRes struct {
   // Test
    // in: body
   Body struct {
     ID uint64
     Name string
      Time string
    }
}

下面这种写法其实很不不便,所有的接口的 Response 下都要多加一层 Body,这是不合理的,Swagger 只是正文,不应该侵入代码,除非原有的构造就是如此,否则不举荐下面的格局。

2、进阶版 swagger:model: 解决了下面的痛点,真正做到了灵便好用。

swagger:model 其实也是一个 swagger 标准,用法非常灵活,具体的用法会在前面介绍,这里就提出用 model 解决 response 的办法。

Response 的正文批改:

// swagger:model old_api_resp
type OldAPIRes struct {
   ID uint64
   Name string
   Time string
}

Route 正文批改:

// ServeAPI serves the API for this record store
func ServeAPI(host, basePath string, schemes []string) error {// swagger:route GET /{id}/checkout SwaggerTest swagger_test_checkout
  //
  // Swagger 测试接口
  //
  // 用于 Swagger 测试
  //
  //     Consumes:
  //     - multipart/form-data
  //     Produces:
  //     - application/json
  //     Schemes: http
  //     Responses:
  //       200: body:old_api_resp
    mountItem("GET", basePath+"/{id}/checkout", nil)

命令批改,- m 是扫描 model:

swagger generate spec -m -o ./swagger.json 

从新生成,而后搞定。

四、Swagger-Yapi

Yapi 一个高效、易用、功能强大的 API 治理平台。

为什么要买通 Swagger 到 Yapi 呢?理由很简略。Swagger 的 SwaggerUI 远没有 Yapi 性能全面,而 Yapi 能反对导入 Swagger.json 格局的接口文档,Swagger 的便利性和 Yapi 的全面性,咱们把二者联合,从而实现更优的后果。

4.1►Nginx 搭建

通过下面的步骤咱们应该曾经在本地生成了咱们接口的 Swagger.json,而 Yapi 曾经反对了手动导入和主动导入两种形式。

手动导入:

主动导入:

咱们须要的是什么?咱们须要的是每次 Swagger 更新之后,Yapi 都会自动更新咱们的接口,那么咱们天然须要应用 Yapi 的主动导入,因而咱们只须要在本人的机器上搭建一个 Nginx 来做动态文件代理,就能实现。

下载并装置 nginx:

sudo yum install nginx -y

装置实现后查看:

rpm -qa | grep nginx

启动 nginx

sudo systemctl start nginx

或是

sudo service nginx start

查看 nginx 状态

sudo systemctl status nginx

或是

sudo service nginx status

4.2►代理文件

进入 nginx 目录

cd /etc/nginx/

在 conf.d 目录下新增须要代理的端口

data 映射的目录依据本人的理论状况,即 swagger.json 所在目录的地位而定。

cd conf.d/
vim yapi.conf
server {
    listen       8888;
    server_name  localhost;

    location /data/ {alias '/home/work/Swagger/swagger-yapi/swagger-json/';}
}

重启 nginx

sudo systemctl restart nginx

sudo service nginx restart

4.3►Yapi 主动同步

ip 对应你本人的机器 ip。

ip 地址能够通过以下命令查看:

hostname -i

如果被提醒了:

阐明门路不对,能够把地址输出浏览器拜访,本人调整到正确即可。

五、结语

Swagger 还有很多的用法,光是通过 swagger - h 命令就能看到很多用法,而它的正文的用法也有很多,针对不同语言也有不同的写法。同理,Yapi 作为一款功能强大的 API 治理平台也是一样的有很多的用法,比方在线 mock 接口等等。本文仅作为一个疾速上手入门 swagger 到 yapi 的办法,通道搭建好之后,更多的用法就能够各位同学本人去开掘。

————————END————————

举荐浏览:

百度直播 iOS SDK 平台化输入革新

百度 APP 基于 Pipeline as Code 的继续集成实际

Go 语言应用 MySQL 的常见故障剖析和应答办法

百度交易中台之钱包零碎架构浅析

基于宽表的数据建模利用

百度评论中台的设计与摸索

基于模板配置的数据可视化平台

退出移动版