🦝

Mockoonがモックサーバーとして優秀だった

2024/12/09に公開

はじめに

はじめまして! e-dash エンジニアの 高尾 です。
こちらはe-dash advent calendar 2024の 9 日目の記事となります。

皆様、プロダクト開発において、APIのモックサーバーは導入されていますでしょうか。
プロダクトで外部APIを利用することは多々あると思いますが、ローカル開発時の接続先って制限があったりして悩みますよね。
そんなときにAPIモックサーバーを導入することで、以下のようなメリットを得ることができます。

  • 開発の柔軟性
    様々なレスポンスパターンを用意することが容易であり、ひいてはローカルでのテストが容易になります。
  • 並行開発の実現
    新機能開発時には、外部APIの開発状況に関係なく、並行して開発を進めることができます。これにより、開発のリードタイムを短縮することが可能です。
  • チーム全体での効率化
    開発者それぞれが同じモックサーバーを使用することで、チーム内での開発環境の統一が図れます。開発環境セットアップも容易になりチーム全体の生産性向上につながります。

今回私が所属するチームにおいてもこれらのメリットを享受するためにモックサーバーの導入を検討、ツール選定を行いました。
本記事ではその中で検証したMockoonについて、基本的な使い方をご紹介した後、導入が適していると思われるユースケースを紹介できればと思います。

前提条件と選定基準

今回APIモックサーバーを採用するにあたり、要件は以下でした。

必須要件

  • チーム全体で共通のモックを利用する
  • 既存のOpenAPI定義ファイルを活用できる

モック対象のOpenAPI定義ファイル自体は提供されていたため、それを最大限利用してIFのアンマッチ抑制や管理コスト削減を目指すことを要件にしました。

推奨要件

  • リクエストパラメータに応じて異なるレスポンスを返却する

1パターンだけの固定レスポンスを返すモックサーバーの場合、ローカル開発で利用するDB上のデータ等と整合性が保てず開発者体験が落ちることが多々あると思います。
現状利用するAPIの仕様上必須ではなかったものの、将来を見越して推奨要件として検討しました。

Mockoonについて

Mockoonは、APIモックサーバーを簡単に作成・管理できるオープンソースのツールです。
主な特徴は以下の通りです。

  • デスクトップアプリケーションとして直感的なGUIインターフェースを提供
  • CLIツールとDockerイメージも提供
  • OpenAPI/Swagger定義のインポート/エクスポート機能
  • ルールベースの動的なレスポンス生成

https://mockoon.com/

Mockoonの基本的な使い方

Mockoonの基本機能について簡単に説明します。
なお、本記事では要件の都合上、既存のOpenAPI定義ファイルがある前提の使い方になりますのでご了承ください。

利用しているOpenAPI定義などはサンプルとして以下に公開しています。
https://github.com/htk-donuts/mockoon-trial

今回モック対象とするAPIは、ユーザーの情報を取得するシンプルなRestful APIです。
以下のID指定でユーザー情報を取るAPIを例に説明していきます。
GET /users/:userId

GUI操作

インストール

こちらからお手元の環境に合わせてインストールできます。
https://mockoon.com/download/

# macOSの場合
brew install --cask mockoon

OpenAPI定義を読み込んで環境の作成

アプリを起動し、メニューにある「Import Swagger 〜」から定義をImportします。
alt text

この際、OpenAPI定義を元にMockoon専用の環境ファイルに変換されるため、そのファイル名・出力先の指定が必要です。
設定後、GUI上に読み込んだAPIたちが表示されていれば成功です!

起動

SettingsタブからポートやURL等の設定が可能です。
設定後、左上の▶ボタンを押下するとモックサーバーが起動します。

早速curlを打ってみましょう。

$ curl http://localhost:3001/users/1
{
  "id": 1,
  "name": "John Doe",
  "email": "john.doe@example.com",
  "age": 30
}%

無事Response 1の応答が返ってきました。
以下の箇所がレスポンスを表しており、フラッグマークがついているレスポンスがデフォルト応答になります。
alt text

なお、ここにはデフォルトで読み込んだOpenAPI定義のExampleが利用されます。

リクエストに応じたレスポンスの設定

Rulesからリクエストに応じてレスポンスを変更することが可能です。
クエリパラメータのuserIdに応じてレスポンスを変えてみます。

id:1id:2Responseをそれぞれ用意します。
alt text

id:1の方のRuleを開いて、以下のようにクエリパラメータuserId equal 1の場合に応答するという追加します。
alt text

同様にid:2の方にもルールを追加します。
最後に、デフォルトの応答を404 NotFoundにしましょう。

準備完了です。リクエストしてみましょう。

$ curl http://localhost:3001/users/1
{
  "id": 1,
  "name": "John Doe",
  "email": "john.doe@example.com",
  "age": 30
}%

$ curl http://localhost:3001/users/2
{
  "id": 2,
  "name": "Jane Smith",
  "email": "jane.smith@example.com",
  "age": 28
}%

# id1,2以外の指定ではデフォルトの404で応答
$ curl -I http://localhost:3001/users/3
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Content-Length: 33
Date: Sun, 01 Dec 2024 05:02:43 GMT
Connection: keep-alive
Keep-Alive: timeout=5

idによってレスポンスが変わることが確認できました。

環境を共有する

今カスタマイズした環境をjsonファイルとして共有することが可能です。
下記から環境ファイルが配置されているディレクトリを開けます。

環境ファイルを共有することでチーム内で共通のモックサーバーを利用することが可能になります。

CLI操作

Mockoon CLIというCLIツールも提供されており、GUIで行った操作をCLIだけで実行することも可能です。
https://mockoon.com/cli/

mockoon-cliのインストール

公式案内の通りnpmでインストールします。

$ npm install -g @mockoon/cli

OpenAPI定義を読み込んで環境の作成

以下コマンドでOpenAPI定義を読み込んでMockoon専用環境ファイルに変換するというGUIでのImportと同じことができます。

$ mockoon-cli import --input openapi.yml --output environment.json  --prettify;

起動

以下で起動です。

$ mockoon-cli start --data environment.json

このenvironment.jsonをGUIから出力したものを指定することで、環境はGUIで管理/修正して、起動だけはCLIで行うということも可能です。

コンテナ起動

チームで共有する場合、各自にMockoonのクライアントアプリケーションをインストールさせてGUI経由で起動するというのは開発者体験を落としてしまいます。
そのためチームで利用する場合は、上記手順の通りCLIでローカル起動するスクリプト等を用意するか、Dockerコンテナ上で起動できるようにしておくことになると思います。

今回はdocker-composeを利用してコンテナ起動も試しました。

# docker-compose.yml
version: '3.8'
services:
  mockoon:
    image: mockoon/cli:latest
    volumes:
      - ./data:/data
    ports:
      - "3000:3000"
    entrypoint: /bin/sh
    command: >
      -c "mockoon-cli start --data /data/environments.json --port 3000"

docker-compose upで起動可能です。簡単にコンテナ起動することができました。

環境ファイルを直接更新してレスポンスをカスタマイズしてみる

GUI操作の項でルールを設定して、リクエストによってレスポンスを変えることができましたが、
もちろん環境ファイルを直接変更することも可能です。やってみます。

まず、先程GUIで終止した内容はどうなっているか確認しましょう。

    {
      "uuid": "eb811180-64c9-44ce-ae18-9ad7ebfe4ee8",
      "type": "http",
      "documentation": "Get user by ID",
      "method": "get",
      "endpoint": "users/:userId",
      "responses": [
        {
          "uuid": "acf18ca1-dbe2-4621-bc31-ccb7208b5685",
          "body": "{\n  \"id\": 1,\n  \"name\": \"John Doe\",\n  \"email\": \"john.doe@example.com\",\n  \"age\": 30\n}",
          "latency": 0,
          "statusCode": 200,
          "label": "Successful response with user details id 1",
          "headers": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "bodyType": "INLINE",
          "filePath": "",
          "databucketID": "",
          "sendFileAsBody": false,
          "rules": [
            {
              "target": "params",
              "modifier": "userId",
              "value": "1",
              "invert": false,
              "operator": "equals"
            }
          ],
          "rulesOperator": "OR",
          "disableTemplating": false,
          "fallbackTo404": false,
          "default": false,
          "crudKey": "id",
          "callbacks": []
        },
        // id:1の応答以外省略
      ],
      "responseMode": null,
      "streamingMode": null,
      "streamingInterval": 0
    }

この状態でも人の目で読めるようになっているのはとてもありがたいです。
今回は、レスポンスを外部ファイルで管理したいというよくあるケースを実現する修正をいれてみます。

-          "bodyType": "INLINE",
-          "filePath": "",
+          "bodyType": "FILE",
+          "filePath": "../responses/user1.json",

bodyTypeFileに変更し、filePathに返したいレスポンスのファイルを指定します。bodyの中身は削除せずとも無視されます。
このようにGUIを使わずとも修正は可能ですが、Mockoon専用の環境ファイルになっているためメンテナンスコストは増えてしまうと思います。
基本的にはGUI操作で修正するのが良いと思いました。

Mockoonを採用すべきケース

以上が今回試してみた基本的なMockoonの利用方法の検証です。
今回Mockoonを触ってみて、以下の点で優れたモックサーバーツールだと感じました。

  • GUI操作による直感的な設定
  • 環境ファイルのチーム内での共有が容易
  • 動的レスポンスの柔軟な設定
  • OpenAPI定義を読み込める

今回はとても簡単なパスパラメータだけでレスポンスを変えてみましたが、
パラメータ数が多かったり更に応答のパターンが複雑だったりすると、コード上で管理するのはなかなか難しくなってくると思います。
それをGUIで直感的に管理できる、これがMockoonを採用する最大のメリットだと感じました。
また、既存のOpenAPI定義があれば、それを元に肉付けしていくだけで良いのもありがたいです。


一方で、以下は運用上注意が必要だと思います。

  • Mockoon専用の環境ファイルになるため、元のOpenAPI定義の直接差分取り込みはできない
  • 固定値を返すだけのモックで十分であれば機能がTooMuchすぎる

特に1点目は注意が必要で、モック対象のAPI定義が変更された際に、OpenAPI定義ではなくMockoonの環境ファイルにも修正内容を反映させなければいけません。
大規模なAPIをモックする場合、その分頻繁に修正が入ると思うため、漏れなく正しく反映する仕組み化が必要になると感じました。
また、固定値を返すだけであれば、やはりOpenAPI定義をそのまま利用できるPrism等のツールが第一候補になると思います。


上記を踏まえ、結論以下のようなケースではMockoonを採用する価値があると考えています。

  • 既存のOpenAPI定義がない場合
  • 頻繁に修正が入ることはないAPIをモックする場合
  • 簡単な応答だけでなく、複雑なパターンの応答が必要な場合

なお、今回のユースケースでは動的なレスポンスは推奨要件であり、OpenAPI定義も既存だったためユースケースとしてはアンマッチと判断。
Mockoonの採用は見送りPrismを採用しています。無念。。。。

おわりに

モックサーバーの選定は、プロジェクトの要件や制約に大きく依存します。
しかしながら、本筋のアプリケーションではないという都合上管理は極力最小限にできるに越したことはないと思います。
今回紹介したMockoonが、皆様のモックサーバー選定の一助になれば幸いです。

採用情報

e-dashエンジニアチームは現在一緒にはたらく仲間を募集中です!
同じ夢について語り合える仲間と一緒に、環境問題を解決するプロダクトを作りませんか?

Discussion