開発効率を上げる！Swaggerで作るWEB APIモック

みなさんは、開発初期の段階でWeb API(以下API)の実装が追いつかずクライアント側が開発できないという経験をしたことはありますか？ クライアント側はAPIがないと開発が滞ってしまうことがありますが、かといってAPIの開発も始まったばかりではすぐに必要なAPIを提供することができません。その問題を解決し、両者でスムーズに開発をすすめるために有効な方法の1つに、APIモックの作成があります。
弊社では、開発初期の段階でSwaggerとその周辺ツールを使ってWeb APIのモックを作成し、スムーズに開発できるようにしています。
Swaggerを使ったAPIモックの作成方法と手順、また気をつけるべき点などを紹介します。

## 目次

1. Swaggerとは？
2. Swagger記法の一例
2. Swaggerのエディター選択
3. SwaggerAPIモックの動かし方
4. 結論
4. まとめ

# Swaggerとは？

Swaggerとは、REST APIを定義するためのフレームワークです。また、それを記述するためのSwaggerEditorやドキュメントツールであるSwaggerUIなどの関連ツール群のことを指します。

## Swaggerを使うメリット

Swaggerを使うメリットとしては、下記のような項目があります。

- YAMLの記法で書ける（※JSONでも書ける）
- YAMLで記述したAPI定義を元に、
        - 多数の言語によるAPIモックアプリケーションを簡単に作成できる
        - APIドキュメントの自動生成ができる
- 各エントリーポイントに対してパラメーターも指定できる
- AWSのAPI Gatewayに反映できる

Swaggerで作るAPI定義はYAMLによる記述が可能なので、1回書いたモックを引用することができて繰り返し同じダミーデータを書く必要がなくなります。
さらに、定義したYAMLファイルを元に下記のようなAPIドキュメントを自動的に生成してくれるSwaggerUIというツールがあります。クライアントに渡すAPIドキュメントをいちいち手書きすることもなくなるのでとても便利です。

![Swagger UI.png](https://qiita-image-store.s3.amazonaws.com/0/43089/670a087a-9553-303c-6aa6-eb1b0817feeb.png "Swagger UI.png")

また、米国等ではSwaggerがREST API定義のデファクトスタンダードになっているようで、最近ではAWSのAPI GatewayでもSwaggerの記法をimportすることができるようになりました。今後様々なサービスでSwaggerが使えるようになる可能性があります。

## Swaggerを使うデメリット

デメリットとしては下記があると感じました。

- 周辺ツールが豊富すぎてベストな開発方法を見つけるのに時間がかかる
- REST APIの定義のために作られているため、モックで実現したい記法がドキュメントになく迷うことがある

まずひとつとして周辺ツールが多いので開発を始める際、調査に時間がかかります。
これについては、エディターの説明やAPIモックサーバーの立ち上げ方でいくつかの開発手法を紹介します。
ふたつめの、迷いがちな記法については後日追って同テックブログにて公開します。（未定)

# Swagger記法の一例

まずはイメージが湧きやすいように、シンプルなSwagger記法(YAML）の一例を載せます。
Swaggerの記法は<a href="http://swagger.io/specification/">ドキュメント</a>にまとまっていますが、一読しただけでは少しわかりにくい部分があるので基本的な構成を紹介します。

```yaml

info:
  # モックのメタデータを記述する
schemes:
  # APIモックサーバーのプロトコルの選択
paths:
  # エンドポイントの記述
definitions:
  # モデル定義の記述
  properties:
    # モデルの詳細定義
    example:
    # 各値の例の記述
```

実際に上記の基本的な構成で記述したシンプルなSwagger YAMLがこちらです。

```yaml

swagger: '2.0'

# モックのメタデータを記述する
info:
  description: |
    This is a sample server Petstore server.  You can find
    out 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: Swagger Petstore
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html

# モックサーバーのプロトコルの選択
schemes:
- http

# エンドポイントの記述
paths:
  /pet/{petId}:
    get:
      tags:
      - pet
      summary: Find pet by ID
      description: Returns a single pet
      operationId: getPetById
      produces:
      - application/json
      parameters:
      - name: petId
        in: path
        description: ID of pet to return
        required: true
        type: integer
        format: int64
      responses:
        200:
          description: successful operation
          schema:
            $ref: '#/definitions/Pet'
        400:
          description: Invalid ID supplied
        404:
          description: Pet not found

# モデル定義の記述
definitions:
  Category:
    type: object

    # モデルの詳細定義
    properties:
      id:
        type: integer
        format: int64
      name:
        type: string
  Tag:
    type: object
    properties:
      id:
        type: integer
        format: int64
      name:
        type: string
  Pet:
    type: object
    required:
    - name
    - photoUrls
    properties:
      id:
        type: integer
        format: int64
      category:
        $ref: '#/definitions/Category'
      name:
        type: string
        # 各値の例の記述
        example: doggie
      photoUrls:
        type: array
        items:
          type: string
      tags:
        type: array
        items:
          $ref: '#/definitions/Tag'
      status:
        type: string
        description: pet status in the store
        enum:
        - available
        - pending
        - sold
```

このような記法でAPIの内容を記述していきます。
こちらのYAMLから生成したAPIモックアプリケーションをローカルに立ち上げると下記のようになります。

↓http://localhost:8080/docs
![Swagger_UI_simple.png](https://qiita-image-store.s3.amazonaws.com/0/43089/37760ea2-977a-5cc4-e16f-5e734f5a6752.png "Swagger_UI_simple.png")

`paths`で指定したパスがAPIドキュメントになっているのがわかります。

下記が、各エントリーポイントのモックの一例です。
↓http://localhost:8080/pet/1

![api_cap2.png](https://qiita-image-store.s3.amazonaws.com/0/43089/9ea2c575-7583-5b21-aaf6-d5e23539655c.png "api_cap2.png")

propertiesで指定したモデルの構成と、exampleで指定した実際の値がモックに反映されているのがわかります。

# Swaggerのエディター選択

記法がなんとなくわかったところで、どのように開発を進めていくかを紹介します。
Swaggerのエディターには下記の3つが存在しています。

- <a href="http://swagger.io/swagger-editor/">SwaggerOnlineエディター</a>
- <a href='https://swaggerhub.com/'>SwaggerHub</a>のエディター
- Localエディター

この3つのエディターのそれぞれのメリット、デメリットを説明します。
また、上記3つのエディターを使ず、手元の慣れたエディターで開発する手法についても紹介します。

## SwaggerOnlineエディターを使う

SwaggerOnlineエディターは、Swaggerが提供している無料のOnlineエディターです。機能が限定されていますが、シンプルな分扱いやすいのが特徴です。
アカウント作成の必要もなく、誰でもすぐ使うことができます。http://editor.swagger.io/#/
機能は本当にシンプルで、

1. 手元にあるYAMLをimportする
2. YAMLを編集してAPIモックアプリケーションを自動生成する
3. 編集したYAMLをexportする

くらいしかありません。

下記は、SwaggerOnlineエディターを使うことのメリット、デメリットの表です。

|  |内容|
|--------|--------|
|   メリット     | ・扱いが簡単<br> ・無料で使える<br>|
|デメリット|・機能が少ない|

簡単なモックを作りたいだけのときにはこちらのエディターで十分だと思います。

## SwaggerHubのエディターを使う

<a href='https://swaggerhub.com/'>SwaggerHub</a>とは、OSSのSwaggerに幾つかの機能を追加して拡張したサービスで、様々な機能を提供してくれます。
OSSのSwaggerとSwaggerHubの機能の比較の表はこちらになります。<a href="https://swaggerhub.com/swagger-open-source-comparison/">比較表</a>

拡張機能の中でもメリットに感じた部分とデメリットに感じた部分を下記の表にしました。

||内容|
|--------|--------|
|   メリット     |   ・チーム（Organization）を設定してエディターの共有ができる<br> ・APIモックサーバーをホスティングしてくれる<br> ・エディターの編集内容をGithubに自動連携できる|
|デメリット|・Githubにpushしたコードをエディタに取り込むことはできない<br> ・ほとんどの機能が有料<br>|

まず注目なのはGithubに自動連携できるということです。Githubのリポジトリと紐付け、エディターでアップデートした分を自動的にcommitしてくれます。これにより、リアルタイムで複数人の開発が可能になります。ただし、手元のエディター(vimなど)で編集し、GithubにpushしたものをSwaggerHubのエディターに取り込むことはできません。
また、デプロイ機能もついており、自前でホスティングしなくてもAPIモックサーバーを提供してくれます。

デメリットは、チームを設定する機能やGithubとの連携機能が有料なことです。登録初期には無料トライアル期間がありますが、数週間のみです。
下記は記事公開時点での無料/有料の機能表です。

![スクリーンショット 2017-05-06 15.11.55.png](https://qiita-image-store.s3.amazonaws.com/0/43089/5d7f6ac3-3826-d936-59af-a0b44d1df394.png "スクリーンショット 2017-05-06 15.11.55.png")

(出典: https://app.swaggerhub.com)

無料なのは、上の3つのみです。

## SwaggerLocalエディターを使う

|  |内容|
|--------|--------|
|   メリット     | ・無料で使える<br> ・pluginを書けばエディターを拡張できる  |
|デメリット|・環境を作る必要がある<br>|

SwaggerLocalエディターはSwaggerOnlineエディターをlocalに立てたものです。

Localエディターの立て方は幾つか方法があるのでSwaggerToolsの公式ドキュメントとOSSとして公開されているコードを参照してください。
(参照: <a href="http://swagger.io/docs/swagger-tools/#swagger-editor-documentation-0">SWAGGER TOOLS DOCS</a>, <a href="https://Github.com/swagger-api/swagger-editor">swagger-editor</a>)

デフォルトの仕様ではSwaggerOnlineエディターと機能はほとんど変わりませんが、pluginを書くことで好きなように拡張できるのが特徴です。
特に拡張などをする気がない方はSwaggerOnlineエディターで十分だと感じましたが、好きなようにエディターを拡張したい方にはおすすめです。

## 手元の慣れたエディターを使う

ここで誰しもが思うのが、手元の慣れたエディターで開発をすすめられないかということではないでしょうか。Swaggerのエディターを使わず、手元の慣れたエディターで開発する方法があります。
SwaggerのYAMLを手元のエディターで編集し、<a href=https://Github.com/swagger-api/swagger-codegen>SwaggerCodegen</a>を使ってAPIモックアプリケーションを生成する手法です。SwaggerCodegenとは、各種言語のAPIモックアプリケーションを吐くコマンドツールです。

さらに、GithubでYAMLを管理すればチーム開発も可能です。編集するメンバーが少人数の場合はこちらの手法は有効です。

|  |内容|
|--------|--------|
|   メリット     | ・開発しやすい<br> ・Githubで管理すればチームで共有可能     |
|デメリット|・自前でホスティングする必要がある(localで立ち上げてテストや確認をする必要がある)<br> ・Swaggerの文法エラーの詳細が出ない|

デメリットとして、他のSwagger専用エディターと違ってSwaggerの文法エラーの詳細を出してくれないという点があります。
その際には、SwaggerOnlineエディターやローカルエディターにYAMLをロードしてエラー箇所を確認するという手段を取る必要があります。そういった点から、こちらの手法はある程度Swaggerの開発に慣れて来た場合にオススメできる方法ですが、慣れたエディターを使うので開発効率が圧倒的に良かったです。


# SwaggerAPIモックの動かし方

エディターを選出してSwaggerのYAMLを記述したら、実際にSwaggerのAPIモックを動かしてみましょう。
APIモックの動かし方は4つあります。

1. SwaggerCodegenを使ってAPIモックアプリケーションを自動生成する
2. 各Swaggerエディター経由でAPIモックアプリケーションを自動生成する
3. SwaggerHubを使う
4. API Gatewayを使う


<img width="686" alt="スクリーンショット 2017-05-15 22.59.40.png" src="https://vasily.qiita.com/files/2f57d6a4-7279-e740-d06b-eebb6e9cb5e9.png">



## SwaggerCodegenを使ってAPIモックアプリケーションを自動生成する

|  | 内容 |
|--------|--------|
| メリット      | ・YAMLをロードするだけで簡単に動くサーバーが作れる<br> ・Swaggerの文法をそのまま適用することができ、exampleが書きやすい       |
| デメリット     | ・自前でサーバーを用意する必要がある |



## 手順
### 1. swagger.yamlを作成する
swagger.yamlを好きなエディターで編集

### 2. swagger-codegenをlocalにダウンロード

```
$ git clone https://Github.com/swagger-api/swagger-codegen
$ cd swagger-codegen
$ ./run-in-docker.sh mvn package
```

(複数のやり方があるようなので自分の環境に合ったやり方を選択する 参照: <a href="https://Github.com/swagger-api/swagger-codegen">SwaggerCodegen</a>)


### 3. コマンドでモックサーバーアプリケーションを生成する

```
$ cd swagger-codegen
$ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -i /path/to/swagger.yaml -l nodejs-server -o samples/server/test/nodejs
```
(今回はnodejsのアプリケーションを作成)

### 4. 生成したサーバーを立ち上げる

```
$ node ./samples/server/test/nodejs/index.js
=> Your server is listening on port 8080 (http://localhost:8080)
Swagger-ui is available on http://localhost:8080/docs
```

### 5. `/docs`と各エントリーポイントを見てみる

`http://localhost:8080/docs`にアクセスする

![スクリーンショット 2017-05-13 15.29.18.png](https://qiita-image-store.s3.amazonaws.com/0/43089/08c8c401-3964-c23c-bab3-7268524cbaa2.png "スクリーンショット 2017-05-13 15.29.18.png")

↓http://localhost:8080/pet/1

![api_cap2.png](https://qiita-image-store.s3.amazonaws.com/0/43089/9ea2c575-7583-5b21-aaf6-d5e23539655c.png "api_cap2.png")

一旦SwaggerCodegenをlocalにダウンロードした後は、手順`3.`から下の手順のみになります。もしもGithubで共有している場合は、YAMLをGithubにPushして共有のサーバーでアプリケーションを立ち上げればチームでアプリケーションを共有できます。

## 各Swaggerエディター経由でAPIモックアプリケーションを自動生成する

|  | 内容 |
|--------|--------|
| メリット      | ・YAMLをロードするだけで簡単に動くサーバーが作れる<br> ・Swaggerの文法をそのまま適用することができ、exampleが書きやすい  |
| デメリット     | ・自前でサーバーを用意する必要がある |

手順はシンプルで、各エディターのヘッダー部分にGenerateServerのボタンがあるのでそこから好きな言語を選択するだけでAPIモックアプリケーションの作成ができます。

<img width="1429" alt="スクリーンショット 2017-05-17 22.02.32.png" src="https://vasily.qiita.com/files/bdb54fc8-93e7-327a-d4d4-a9bbb7960b59.png">

上記で説明したエディター3種類のSwaggerEditorのどれもがこのGenerateServerの機能を提供しています。


## SwaggerHubを使う

|  | 内容 |
|--------|--------|
| メリット      | ・ホスティングしてくれる<br> ・Swaggerの文法をそのまま適用することができ、exampleが書きやすい|
| デメリット     | ・有料 |

こちらの画面がSwaggerHubのエディターです。
記述したエントリーポイントを開き、`Execute`ボタンを押すとモックサーバーのURLを返してくれるのでそこにアクセスするだけです。
<img width="1428" alt="swagger-hub-before.png" src="https://vasily.qiita.com/files/840a85bc-c306-be67-dacf-f5dbccd70641.png">


<img width="1430" alt="swagger-hub-after.png" src="https://vasily.qiita.com/files/78fc8332-2adc-a421-5022-6af38ad1755e.png">

## API Gatewayを使う

|  | 内容 |
|--------|--------|
| メリット      | ・サーバーを用意してくれる       |
| デメリット     | ・Swaggerでサポートされている文法とAPI Gatewayでサポートされている文法が微妙に違う(exampleが使えない)<br> ・API定義をインポートした後のコンソール上での作業が多い|

1. SwaggerYamlをロードする
2. 各エントリーポイントごとにMockサーバーを立てる

`2.`の手順が長いので、画面で説明します。

①YAMLロード後の画面からエントリーポイントを選択後(今回の場合はpetsのGET)、総合リクエストを選択
![api-gateway1.png](https://vasily.qiita.com/files/c4989566-d368-b5e4-cb8f-7ca67bf9510a.png)
②Mockを選択
![api-gateway2.png](https://vasily.qiita.com/files/96a1fd9f-b41a-7750-8899-6487ee3f6077.png)
③保存後、YAMLロード後の画面に戻って`総合レスポンス`を選択後し、本文マッピングテンプレートでモックとして返したいモデルを選択
![api-gateway4.png](https://vasily.qiita.com/files/ad731674-9096-579f-ad9d-de364f82c848.png)
![api-gateway5.png](https://vasily.qiita.com/files/764e8324-4db2-e72c-d0fe-9d86cc9be505.png)
④YAMLロード後の画面に戻り、テストを選択
こちらの画面でテストを選択後、モックのレスポンスが表示される
![api-gateway6.png](https://vasily.qiita.com/files/fa385f8d-3ac3-f7da-9ccd-93b66ae5a571.png)
⑤YAMLロード後の画面に出ているURLにアクセスするとモックを見ることができる


このように、モックにするとなると画面上での工程が多かったです。
エントリーポイントが複数ある場合においてはSwaggerCodegenやSwaggerHubのほうがオススメです。
また、API Gatewayではexampleが使えなかったり、definitionsのモデルを必ずキャメルケースで定義する必要があるなど、Swagger定義の仕様と異なる部分があったので手こずりました。

# 結論

エディターの選択とSwaggerAPIモックの動かし方を紹介しましたが、どのツールを使うかは好みやシーンによって様々です。
参考までに、最終的に採用した開発方法は下記のような感じです。

<img width="625" alt="スクリーンショット 2017-05-18 13.32.16.png" src="https://vasily.qiita.com/files/7113d611-3fa6-7a8e-1cf7-6119b720b9bb.png">


vimで編集したSwaggerYAMLをGithubで管理し、localでテストする際はSwaggerCodegenで生成したAPIモックアプリケーションをlocalで立ち上げてテストしています。また、テストできたらSwaggerYAMLを共用サーバーにデプロイし、SwaggerCodegenで生成したアプリケーションを立ち上げてチームで共通のモックアプリケーションを見られるようにしています。
上記を採用した理由としては、

1. 手元の慣れたエディターで編集したい
2. チームで1つのSwaggerYAMLを共有したい
3. 無料

があります。

# まとめ
SwaggerはAPIのモックを作成してくれ、ドキュメントにもまとめてくれる機能があるのでとても便利です。ぜひSwaggerのAPIモックを試してみてください！