OpenAPI（Swagger）のAPI開発Docker環境を整備した（yaml分割編集、SwaggerUI表示、モックサーバー、静的HTML出力）

# はじめに
OpenAPI（Swagger)でのAPI開発をプロジェクトで導入する際、
OpenAPIのyamlの書き方を覚えることよりも、
チーム開発するための最善の環境（ツール）選定に苦労したりします。

WEB上の[SwaggerEditor](https://editor.swagger.io/)を利用することや、
[SwaggerHub](https://swagger.io/tools/swaggerhub/)というサービスを利用するという手もありますが、
いろいろとネックとなるところがあります。[^1]　[^2]
[^1]: SwaggerEditorはWEB上に案件の機密情報（API仕様書）をアップロードする必要がある点などがネックだったり
[^2]: SwaggerHubは機能は便利ですが、チーム開発のためには有料プラン（結構高い）を使う必要がある点がネックだったり

各自のローカルPCで各種ツールを利用できるような環境を作ってしまうのが便利かなと思い、
一式のツールをまとめたDocker環境を整備しました。


# 環境概要
完成品の環境コードはこちらに公開しています。
https://github.com/MinatoNaka/OpenApiDocker

READMEに記載されている手順でDocker環境を構築すれば
すぐに利用可能です。

この環境は、下記の機能を備えています。

* SwaggerUIによるドキュメント表示
* ReDocによるドキュメント表示
* yamlのファイル分割記述可能（自動結合）
* 単一の静的HTMLでドキュメント出力
* APIモックサーバ

それぞれの機能について簡単に解説します。
※各機能の具体的な使い方は、GitHubのREADMEを確認してください。

# SwaggerUIによるドキュメント表示
環境構築し、http://localhost:8011/ にアクセスすると、
自分で記述したAPI定義のyamlファイルを
SwaggerUIでキレイに表示できます。

このUIは見慣れている人も多いと思います。

![screencapture-localhost-8011-2021-03-04-18_02_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297693/118ae769-7b26-f6c3-8e38-376c802fe6f8.png)


# ReDocによるドキュメント表示
http://localhost:8012/ にアクセスすると、
[ReDoc](https://github.com/Redocly/redoc)でAPIドキュメントを表示できます。

SwaggerUIと同じようにyaml情報をキレイに表示してくれるものですが、
SwaggerUIとは見た目がかなり違います。

SwaggerUIとReDocで好みの方を利用してください。

![screencapture-localhost-8012-2021-03-04-18_17_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297693/2e3ded6d-006a-7d99-2630-b2b701d218be.png)

ちなみに、PayPayのAPIドキュメントはReDocが使われていて非常に見やすかったりします。
https://www.paypay.ne.jp/opa/doc/jp/v1.0/preauth_capture

# yamlのファイル分割記述可能（自動結合）
この環境では、 `/openapi/index.yaml` にAPI仕様を記述していきます。
（環境構築した時点でサンプルのAPIドキュメントがすでに記述されています）

通常は、1つのyamlファイルに全てのAPI仕様を記述していきますが、
APIの量が多い場合は1つのファイルに全て記述すると
ファイル行数が多すぎて単純に見づらいし、
チーム開発での差分管理などもしづらくなります。

この環境では、yamlファイルを分割して記述することが可能です。

例えば、下記のようなyamlファイルのinfoの記述を別ファイルに切り出したい場合。

```yaml:openapi/index.yaml
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
```

info配下の記述を別ファイルに移動します。

```yaml:openapi/info/index.yaml
version: 1.0.0
title: Swagger Petstore
license:
  name: MIT
```

そして、元のファイルではこのように `$ref` で切り出したファイルを参照します。

```yaml:openapi/index.yaml
info:
  $ref: './info/index.yaml'
```

この様にyamlファイルを分割して記述することで、
本体のファイルはすっきりし、管理もしやすくなると思います。

分割されたファイルはそのままではSwaggerUIやReDocで表示することはできません。
分割されたファイルを1つのファイルに結合し、
それをSwaggerUIやReDocに読み込ませる必要があります。

ファイルの結合をするために、chokidarとswagger-mergerというツールを利用しています。
chokidarで、ファイルの変更（追加、編集、削除）を常に監視し、
ファイルが変更された場合自動でswagger-mergerによって1つのyamlファイルに結合しています。

この環境ではこの様に自動でファイル結合し、
結合したファイルをSwaggerUIやReDocで読み込む設定をしています。

ちなみに、私が愛用しているJetBrainsのIDE（PhpStormやRubyMine）では、
[OpenAPI Specifications](https://plugins.jetbrains.com/plugin/14394-openapi-specifications/)というプラグインを入れておけば、
上記のような自前の処理を入れなくても、
yamlを分割して記述し、そのままエディタ上で表示することができます。
（ファイルを結合してくれるわけではなく、分割した状態のまま表示できるだけ）

# 単一の静的HTMLでドキュメント出力
APIドキュメントを、単一の静的HTMLで出力することができます。

単一の静的HTMLとはつまり、
他のCSSやJSファイルなどに依存していない、
1枚のファイルだけで表示可能なHTMLファイルです。

このDocker環境を構築できない上流工程の人、エンジニアじゃない人、会社外部の人
などにAPI仕様書を提供する必要がある場合、
このHTMLを1枚渡してブラウザで表示してもらえば
キレイなUIで確認してもらうことができます。

このDocker環境では、ReDocCLIというツールを使って、
ReDocのUIの静的HTMLを出力可能にしてあります。

# APIモックサーバ
[APISprout](https://github.com/danielgtaylor/apisprout)というツールを使った、APIモックサーバを利用可能です。

http://localhost:8010 でモックAPIにリクエスト可能になっています。
APIにリクエストすると、yamlの定義に従ってjsonレスポンスが返却されます。

このAPIモックサーバを利用することで、
フロントエンド実装担当者は、APIの完成を待たずに、
モックを利用して実装を進めることが可能です。

リクエストヘッダーに `Prefer: status=409` のようにレスポンスの種類を指定することで、
特定のレスポンスを返却させることが可能です。
※サンプルAPIドキュメントの場合、`Prefer: status=default`と記述すればエラーレスポンスが返却される

# おわりに
今回OpenAPI関連の色々なツールに触れました。
今後より良いツールを発見したら、
このDocker環境もアップデートしていきたいと思います。