モックAPIサーバーにPrismが良かったので使ってみた


Prismとは

Prism (https://stoplight.io/open-source/prism/) は、OpenAPIの記述に基づいてランダムなダミーレスポンスを返してくれるAPIモックツールです。

何が良いのか?

設計通り のレスポンスが、自動で生成されて返却される

これは圧倒的なアドバンテージではないでしょうか?
もし自力でAPIのモックを用意しようとする場合、フロントエンド単体で完結させようとしたら以下のようになると思います。

  • APIの仕様書を見てレスポンスのスキーマを確認し
  • スキーマに基づいてそれっぽいダミーデータをチマチマと書いて
  • アプリケーション内にレスポンスを返す用のjsonファイルを作ったりして
  • ダミーデータを使う時とそうでない時で、HTTP通信部分のソースを書き換えて
  • 実際にダミーを取ってきてみたらスキーマ通りでないものだったからダミーデータを作り直して
  • 動くようになった頃にはAPIの仕様変更が起きたからまたダミーデータを作り直して ....

フロントエンド開発側としてはダミーでちゃちゃっと試したいはずなのに、そうはいかなさそうです。

これに対して、APIの仕様書通りに自動でダミーデータを作ってくれるのであれば、上記の大半の作業が不要になります。

Prism VS In-memory-web-api

私が現在開発で使っているAngularは、公式でIn-memory-web-api(https://github.com/angular/in-memory-web-api) があり、それを使っても擬似的にAPIサーバーとしてHTTP通信部分の開発をすることができます。

どちらを導入する方が望ましいか、以下の観点にて検討をしました。
- モックAPI/実APIの切り替え容易性
- APIの修正、拡張に伴うダミーデータ周りの修正容易性

モックAPI/実APIの切り替え容易性

・ In-memory-web-apiの場合
公式ドキュメント(https://angular.jp/tutorial/toh-pt6) でも、モックを使う場合にはモジュールを利用する部分で使うソースコードを切り替えるように書かれています。

HttpClientModule,

// The HttpClientInMemoryWebApiModule module intercepts HTTP requests
// and returns simulated server responses.
// Remove it when a real server is ready to receive requests.
HttpClientInMemoryWebApiModule.forRoot(
  InMemoryDataService, { dataEncapsulation: false }
)

ローカルの時はInMemoryWebApiModuleを使うようにして、修正してgitに上げる時にはここはコメントアウトして...と気にかけなければならないわけですね。

・ Prismの場合
Prismと実APIの違いは、リクエストを送るAPIだけです。Prismは localhost:4010 がデフォルトでモックサーバーとして動くので、フロントエンド側はAPIのrootURLを環境変数で切り替えられるようにすれば、ソースコードの修正なくコマンドの切り替えだけで済みます。

APIの修正、拡張に伴うダミーデータ周りの修正容易性

・ In-memory-web-apiの場合
これはあくまでHTTP通信部分を擬似的にやってくれているだけですので、ダミーデータは自分自身で書く必要があります。したがって、前述のチマチマ自分でダミーを作る作業とは大きく変わりません。

・ Prismの場合
ダミーデータを修正するという必要が全くありません。なぜならOpenAPIに書いてある通りのものが自動生成されるのですから。

判定:Prismの圧勝

導入方法

ここまで大いに持ち上げてきたPrism、使うのが手間だったら結局考えものですが、Prismを動かすという部分に関して言えば非常に簡単です。

前提条件

  • docker / docker-composeがクライアント端末に入っていること
    環境を汚す事なく、OpenAPIを使っているどのアプリケーションにもそのまま持ってこれるため、CLIによるクライアント端末へのインストールではなくdockerコンテナを立てるのが良いと思います。
  • OpenAPI v2 or v3で書かれたAPIドキュメントがあること
    これが無いことにはやりようがありませんが、APIのドキュメント化にもってこいですし、Prism関係なくともあるべきだと思います。

手順

1. Prismを動かすコンテナ用にdocker-compose.yamlを作成

中身は以下の通りです。

version: '3'

services:   
 prism:
   image: "stoplight/prism:3.3.4"
   ports:
     - "4010:4010"
   volumes:
     - "[path_to_your_opeapi.yaml]/:/tmp"
   command: "mock -h 0.0.0.0 -d /tmp/openapi.yaml"

2. コンテナの起動

$ docker-compose up

終わりです。openapi.yamlが正しく記述できているなら、ログにもAPI一覧が表示されるかと思います。

$ docker-compose logs

prism_1  | [7:11:08 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/hoge
prism_1  | [7:11:08 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/fuga

あとは実際にこのAPIを叩いてみると、無事にそれっぽいレスポンスが返ってくるのが確認できるでしょう。

$ curl localhost:4010/hoge

終わりに

フロントエンド開発の救世主となるPrismですが、実際APIの品質向上にも有用そうです。
Prismが OpenAPIの記述にしたがってランダムなデータ を作るので、設計漏れだったデータがフロントエンドに返ってくることもあるためです。
数値の桁数、文字制限....などなど、手動では見逃しがちなものもランダムに生成してくれます。もちろんランダムなので、網羅的にそういった条件のチェックができるわけでは無いので頼りきりはできませんが、開発フェーズにおいては、パターンを気にしながら手動で作るよりも良いデータが生成されるのではないでしょうか?