超効率的!Swagger-Yapiの秘密

写真

はじめに:フロントエンドとバックエンドの両方の開発は、インターフェースのドキュメントによって多かれ少なかれ苦しめられていると思います。フロントエンドは、バックエンドによって提供されるインターフェイスのドキュメントが実際の状況と矛盾していると不平を言うことがよくあります。また、バックエンドは、インターフェイスドキュメントの作成と保守に多くのエネルギーを消費し、更新するには遅すぎることが多いと感じています。実際、フロントエンドがバックエンドを呼び出す場合でも、バックエンドがバックエンドを呼び出す場合でも、優れたインターフェイスドキュメントが期待されます。ただし、時間の経過とバージョンの反復により、インターフェイスドキュメントがコードに追いつかないことがよくあり、以前のクラスメートがインターフェイスドキュメントの明確な引き渡しなしに去り、重くて複雑なプロジェクトであり、再評価するのは非常に困難です。最初から作成する必要があります。ですから、強制によってすべての人を規制するだけでは十分ではありません。SwaggerからYapiに到達する方法を研究しました。これを使用すると、コードを書き終えるたびに、コメントを変更して送信するだけで済み、Yapiはインターフェイスドキュメントを自動的に変更できます。

全文は8199語で、推定読書時間は21分です。

1.Swaggerの概要

Swaggerは、RESTful Webサービスを生成、記述、呼び出し、および視覚化するための標準的で完全なフレームワークです。仕様に従って、インターフェイスとインターフェイス関連の情報を定義する必要があります。Swaggerから派生した一連のプロジェクトとツールを通じて、さまざまな形式のインターフェイスドキュメントを生成したり、複数の言語でクライアント側とサーバー側のコードを生成したり、オンラインインターフェイスのデバッグページなどを作成したりできます。

このように、新しい開発モードに応じて、新しいバージョンや反復バージョンを開発する場合は、Swagger記述ファイルを更新するだけで、インターフェイスドキュメントとクライアント側サーバーコードを自動的に生成できるため、呼び出し側のコード、サーバー側のコード、およびインターフェイス。ドキュメントの一貫性。

2.Swaggerビルド

次の手順は、正常に実行できる環境をすでに構築しています。

go-swagger公式チュートリアルで最も完全なチュートリアルを見ることができ、有能な人は公式チュートリアルに直接行くことができます。

2.1►インストール

写真

上記のダウンロード方法はすべて実行可能ですが、すべての状況に対応するために、これを選択してコードを直接ダウンロードしてください。

写真

コマンドを単純化するために、実際には2つのことを行います。

1.clonego-swaggerのコード。

2.スワガーを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<[email protected]> [email protected]
//
//     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 的常见故障分析和应对方法

BaiduTradingPlatformのウォレットシステムアーキテクチャの分析

ワイドテーブルに基づくデータモデリングアプリケーション

Baiduコメントセンターの設計と調査

テンプレート構成に基づくデータ視覚化プラットフォーム

おすすめ

転載: juejin.im/post/7116729520681549854
おすすめ