Swaggerを使ってモックサーバを立てるまでの手順

この記事では以下の内容について記述しています。

- `Swagger`の基礎概念
- `Swagger Editor`を使ったAPIのドキュメント作成
- `Swagger`で作成したAPIのドキュメントを元にモックサーバを立てる

## `Swagger`とは?

[公式](https://swagger.io/)より

>Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS), enabling development across the entire API lifecycle, from design and documentation, to test and deployment.


*SwaggerはOpenAPI（OAS）のための世界最大のAPI開発フレームワークであり、APIのライフサイクル全体にわたって、設計からドキュメント化、テストおよびデプロイまでを可能にします。*

という事なので、APIの仕様設計だけではなく、テストやデプロイまでしてくれる便利ツールです。

### 基本用語

`Swagger`を学ぶと色んな用語があっちこっち飛んでくるので、先にここで話をまとめておきます。
今回は必要最低限の用語と使うやつの名前だけピックアップしました。

- [Swagger Specification](https://qiita.com/disc99/items/37228f5d687ad2969aa2)
  - Swaggerを扱う上で中心となる概念で、Swaggerの仕様に準じた、RESTful APIインターフェイスを記述するためのフォーマット(`YAML/JSON`)。
- [Swagger Editor](http://editor.swagger.io/)
  - `Swagger Specification`のエディタ。慣れるまで時間がかかる。
- [Swagger UI](https://swagger.io/swagger-ui/)
  - `Swagger Specification`から動的にドキュメントを生成するツール。とても見やすい。
- [Swagger Codegen](http://editor.swagger.io/)
  - Swagger Editorで作成した内容をそのままコードに書き出す。様々な言語に対応しており、言語だけでなくFWにも対応している。


### `Swagger Editor`を使って`Swagger Specification`を作成し、APIの仕様を作成する。

詳細な文法はここを参照する。
>[PENAPI SPECIFICATION](https://swagger.io/specification/)

ここでは@Fendo181が作成した`lumen`の簡単なAPIを例に作成していきます。

>https://github.com/Fendo181/lumen_authors_api

````
# Get all authors 
GET /api/authors

# Get one author
GET /api/authors/23

#Create an author
POST /api/authors

#Edit an author
PUT /api/authors/23

# Delete an author
DELETE /api/authors/23
````

>詳細:https://github.com/Fendo181/lumen_authors_api/issues/2

これを例にして`Swagger Editor`でドキュメントを作成してみます。


```yaml
swagger: '2.0'
info:
  description: |
    サンプルです. 
    
    You can findout more about Swagger at 
    [http://swagger.io](http://swagger.io) or on 
    [irc.freenode.net, #swagger](http://swagger.io/irc/).
  version: "1.0.0"
  title: Lumen Authors API 
  contact:
    email: fendo181git@gmail.com
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
# host: petstore.swagger.io
# basePath: /v2

tags:
- name: authors
  description: Authors Info
  externalDocs:
    description: Find out more
    url: http://swagger.io
# schemes:
# - http
paths:
  /authors:
    get:
      tags:
      - authors
      summary: Get all author by id
      consumes:
      - application/json
      - application/xml
      produces:
      - application/json
      - application/xml
      responses:
        200:
          description: Successful
          schema:
           $ref: '#/definitions/Author'
    post:
      tags:
      - authors
      summary: Create an new author
      produces:
      - application/json
      - application/xml
      parameters:
      - in: body
        name: body
        description: Add New Author 
        required: true
        schema:
          $ref: '#/definitions/Author'
      responses:
        200:
          description: Success
  /authors/{id}:
    get:
      tags:
      - authors
      summary: Get an author by id
      produces:
      - application/json
      - application/xml
      parameters:
      - name: id
        in: path
        description: The id that needs to be fetched.  
        required: true
        type: string
      responses:
        200:
          description: successful 
          schema:
           $ref: '#/definitions/Author'
        400:
          description: Invalid id supplied
        404:
          description: User not found
    put:
      tags:
      - authors
      summary: Updated author by id
      description: Update Author info
      produces:
      - application/json
      - application/xml
      parameters:
      - name: id
        in: path
        description: name that need to be updated
        required: true
        type: string
      - in: body
        name: body
        description: Updated user object
        required: true
        schema:
          $ref: '#/definitions/Author'
      responses:
        200:
          description: author info
    delete:
      tags:
      - authors
      summary: Delete author by id
      description: This can only be done by the logged in user.
      produces:
      - application/json
      - application/xml
      parameters:
      - name: id
        in: path
        description: The name that needs to be deleted
        required: true
        type: string
      responses:
        200:
          description: Deleted Successfully
definitions:
  Author:
    type: object
    properties:
      id:
        type: integer
        format: int64
      name:
        type: string
      email:
        type: string
      github:
        type: string
      twitter:
        type: string
      location:
        type: string
      latest_article_published:
        type: string
externalDocs:
  description: Find out more about Swagger
  url: http://swagger.io
# Added by API Auto Mocking Plugin
host: virtserver.swaggerhub.com
basePath: /Fendo181/APP/1.0.0
schemes:
 - https
 - http
```



この`ymal`で書かれた`Swagger Specification`（左）を元に`Swagger UI`(右)で簡単にAPIのドキュメントを生成する事が可能です。

![image](https://git.pepabo.com/storage/user/553/files/026ae600-1198-11e8-8a74-26aaf4abc0bb)


この様に手順としては`Swagger Editer`で`Swagger Specification`を記述して、`SwaggerUI`を見ながら、APIの仕様を設計していく方針になると思います。

また作成したAPIは`SwaggerHub`で公開する事が可能です。

https://app.swaggerhub.com/apis/Fendo181/APP/1.0.0


## モックサーバを立てる。

[SwaggerHub](https://app.swaggerhub.com/)からサーバファイルを出力してモックサーバを構成してみましょう。`SwaggerHub`の`server`から、指定の環境を選択してファイルを出力します。

今回は`nodejs-server`で考えます。

![image](https://git.pepabo.com/storage/user/553/files/c8b66f9c-1282-11e8-81ef-7f7ca971a403)

中身の構成は以下の様になっている。

```sh
# tree nodejs-server-server-generated -L 1                                                                         [~/src/fendo181/lumen_authors_api][add-swagger-spec]
nodejs-server-server-generated
├── README.md
├── api
│   └── swagger.yaml  #swaggerファイル
├── controllers
│   └── Authors.js 
├── index.js
├── node_modules
├── package-lock.json
├── package.json
├── service
│   └── AuthorsService.js  
└── utils
    └── writer.js
```

`swagger.yaml`は`SwaggerHub`で記述した`Swagger Spec`ファイルがそのまま書き込まれています。
この`swagger.yaml`をもとにサーバの処理が記述されているのが、`Authors.js `です。
ここの`Authors`は任意の名前にになります。

### ブラウザでSwagger UIを確認する。

`npm install`を実行する。

```sh
$ npm start                                                           

> lumen-authors-api@1.0.0 prestart /Users/futoshi.endo/src/fendo181/lumen_authors_api/nodejs-server-server-generated
> npm install
up to date in 0.797s

> lumen-authors-api@1.0.0 start /Users/futoshi.endo/src/fendo181/lumen_authors_api/nodejs-server-server-generated
> node index.js

Your server is listening on port 8080 (http://localhost:8080)
Swagger-ui is available on http://localhost:8080/docs
```

`http://localhost:8080/docs`にアクセスして`Swagger UI`を確認します。

![image](https://git.pepabo.com/storage/user/553/files/f3e4daa8-1310-11e8-875b-e1089a3f7907)

ここで各エンドポイント毎の処理を確認する事もできます。`Try It Out`でブラウザ上で`Response`を確認する事ができます。試しに`GET`の処理を確認してみましょう。
![20180216130151](https://git.pepabo.com/storage/user/553/files/a603997e-1319-11e8-8f8b-0d41e0b83238)

### curlで確認

`GET`

```sh
$ curl -X GET --header 'Accept: application/json' 'https://virtserver.swaggerhub.com/Fendo181/APP/1.0.0/authors'  
{
  "id" : 0,
  "name" : "string",
  "email" : "string",
  "github" : "string",
  "twitter" : "string",
  "location" : "string",
  "latest_article_published" : "string"
}
```

### 参考文献

- [外部連携APIのモックサーバをSwaggerを利用して作る](http://lab.aratana.jp/entry/2016/11/02/091504)
- [SwaggerでRESTful APIの管理を楽にする](https://qiita.com/disc99/items/37228f5d687ad2969aa2#swagger%E9%96%A2%E9%80%A3%E7%94%A8%E8%AA%9E)