🫥

docker で外部連携 API をモックで構築する

2023/11/26に公開

概要

外部 API がまだシステム連携できていないときなど、その部分をモックにしてテストしたい場合があります。
外部 API へのリクエストとレスポンスをスタブにするモックサーバーを docker image を使って簡単に構築する方法を 2 つ記載します。

prism

まず、モックサーバをprismを使用して構築する方法を記載します。

docker imageも提供されているため比較的簡単に構築できます。
外部 API のリクエスト情報やレスポンス情報は OpenAPI v2(旧 Swagger)や OpenAPI v3.x ドキュメント形式で記述します。

今回は、外部 API の情報は OpenAPI のサンプルを使用しました。

上記のサンプルを今回は./mock/api-with-examples.yamlに格納し、
以下のように docker-compose.ymlを作成することで外部 API をスタブにすることができました。

version: "3.7"
services:
  app01:
    build: ./app01
    command: ["npm", "run", "start:dev"]
    tty: true
    ports:
      - 3000:3000
    volumes:
      - ./app01:/usr/src/app
    environment:
      - EXTERNAL_API_HOST=mock-server
      - EXTERNAL_API_PORT=4011
    networks:
      - default_network
  mock-server:
    image: stoplight/prism:5.5.1
    command: "mock -h 0.0.0.0 /data/api-with-examples.yaml"
    volumes:
      - ./mock/api-with-examples.yaml:/data/api-with-examples.yaml
    ports:
      - 4010:4010
    networks:
      - default_network

networks:
  default_network:

docker compose up -dで起動します。
prismを動かすポイントは、command に-h 0.0.0.0を記載することと、prism のポートを4010とすることです。
モックにした外部 API へは service 名:4010(上記例の場合http://mock-server:4010)でアクセスできます。

また、以下のようにhostnameを指定してhostnameで指定した値:4010(以下の例の場合http://prism:4010)とアクセスすることもできます。

version: "3.7"
services:
  app01:
    # ----- 略 -----
    environment:
      - EXTERNAL_API_HOST=prism
      - EXTERNAL_API_PORT=4010
    networks:
      - default_network
  mock-server:
    image: stoplight/prism:5.5.1
    command: "mock -h 0.0.0.0 /data/api-with-examples.yaml"
    hostname: prism
    volumes:
      - ./mock/api-with-examples.yaml:/data/api-with-examples.yaml
    ports:
      - 4010:4010
    networks:
      - default_network

また、以下のようにaliasesを指定してaliasesで指定した値:4010(以下の例の場合http://prism.mock.api:4010)でアクセスすることも可能でした。

version: "3.7"
services:
  app01:
    # ----- 略 -----
    environment:
      - EXTERNAL_API_HOST=prism.mock.api
      - EXTERNAL_API_PORT=4010
    networks:
      - default_network
  mock-server:
    image: stoplight/prism:5.5.1
    command: "mock -h 0.0.0.0 /data/api-with-examples.yaml"
    volumes:
      - ./mock/api-with-examples.yaml:/data/api-with-examples.yaml
    ports:
      - 4010:4010
    networks:
      default_network:
        aliases:
          - "prism.mock.api"

mockoon

次に、モックサーバをmockoonを使用して構築する方法を記載します。

こちらもdocker imageも提供されているため比較的簡単に構築できます。
外部 API のリクエスト情報やレスポンス情報は、mockoon 専用のデスクトップアプリケーションを使って作成します。
デスクトップアプリケーションの使い方は公式ページの tutorialsでわかりやすく説明されているので省略します。
mockoon は、任意の port を上記のデスクトップアプリケーションで自由に設定することができます。
レスポンスの書き方については、個人的には少し独特な印象を受けました。レスポンスの書き方についてはこちらをご覧ください。

以下が作成例です。

mockoon sample

上記のように設定すると、以下のデータが windows の場合は、C:\Users\<user name>\AppData\Roaming\mockoon\storageに json 形式で格納されます。

{
  "uuid": "70d90045-52cc-436e-a12d-468c453c65a9",
  "lastMigration": 29,
  "name": "Todo API",
  "endpointPrefix": "",
  "latency": 0,
  "port": 4011,
  "hostname": "",
  "folders": [],
  "routes": [
    {
      "uuid": "356eac0e-7b74-4754-91f4-09ac77b337c9",
      "type": "http",
      "documentation": "",
      "method": "get",
      "endpoint": "todo",
      "responses": [
        {
          "uuid": "fe68335a-3b0a-40c0-ae05-36693c9b8a08",
          "body": "{\r\n  \"todoList\": [\r\n    {{#repeat 3}}\r\n    { \r\n      \"id\": \"{{faker 'string.uuid'}}\",\r\n      \"title\": \"{{faker 'person.firstName'}} {{faker 'person.lastName'}}\",\r\n      \"status\": \"{{oneOf (array 'New' 'Ready' 'In progress' 'Done' 'Pending' 'Postponed' 'Canceled')}}\",\r\n      \"memo\": \"{{oneOf (array '' 'memo')}}\",\r\n      \"registrationDate\": \"{{oneOf (array '2023-11-01T00:00:00.000Z' '2023-11-02T00:00:00.000Z' '2023-11-03T00:00:00.000Z')}}\",\r\n      \"updateDate\": \"{{oneOf (array '2023-11-03T00:00:00.000Z' '2023-11-04T00:00:00.000Z')}}\",\r\n    }\r\n    {{/repeat}}\r\n  ]\r\n}",
          "latency": 0,
          "statusCode": 200,
          "label": "",
          "headers": [],
          "bodyType": "INLINE",
          "filePath": "",
          "databucketID": "",
          "sendFileAsBody": false,
          "rules": [],
          "rulesOperator": "OR",
          "disableTemplating": false,
          "fallbackTo404": false,
          "default": true,
          "crudKey": "id"
        }
      ],
      "enabled": true,
      "responseMode": null
    }
  ],
  "rootChildren": [
    {
      "type": "route",
      "uuid": "356eac0e-7b74-4754-91f4-09ac77b337c9"
    }
  ],
  "proxyMode": false,
  "proxyHost": "",
  "proxyRemovePrefix": false,
  "tlsOptions": {
    "enabled": false,
    "type": "CERT",
    "pfxPath": "",
    "certPath": "",
    "keyPath": "",
    "caPath": "",
    "passphrase": ""
  },
  "cors": true,
  "headers": [
    {
      "key": "Content-Type",
      "value": "application/json"
    }
  ],
  "proxyReqHeaders": [
    {
      "key": "",
      "value": ""
    }
  ],
  "proxyResHeaders": [
    {
      "key": "",
      "value": ""
    }
  ],
  "data": []
}

作成された json ファイルを今回は開発環境の./data/todo.jsonに格納し、以下のdocker-compose.ymlを作成しました。
docker compose up -dで起動し外部 API をスタブにすることができました。

version: "3.7"
services:
  app01:
    build: ./app01
    command: ["npm", "run", "start:dev"]
    tty: true
    ports:
      - 3000:3000
    volumes:
      - ./app01:/usr/src/app
    environment:
      - EXTERNAL_API_HOST=mock-server
      - EXTERNAL_API_PORT=4011
    networks:
      - default_network
  mock-server:
    image: mockoon/cli:5.1.0
    command: ["--data", "data"]
    ports:
      - 4011:4011
    volumes:
      - ./data/todo.json:/data:readonly
    networks:
      - default_network

networks:
  default_network:

モックにした外部 API へは service 名:<mockoonのデスクトップアプリケーションで指定したポート>(上記例の場合http://mock-server:4011)でアクセスできます。

また mockoon も、以下のようにhostnameを指定してhostnameで指定した値:<mockoonのデスクトップアプリケーションで指定したポート>(以下の例の場合http://mockoon:4011)とアクセスすることもできます。

version: "3.7"
services:
  app01:
    # ----- 略 -----
    environment:
      - EXTERNAL_API_HOST=mockoon
      - EXTERNAL_API_PORT=4011
    networks:
      - default_network
  mock-server:
    image: mockoon/cli:5.1.0
    hostname: mockoon
    command: ["--data", "data"]
    ports:
      - 4011:4011
    volumes:
      - ./data/todo.json:/data:readonly
    networks:
      - default_network

networks:
  default_network:

また、こちらも以下のようにaliasesを指定してaliasesで指定した値:<mockoonのデスクトップアプリケーションで指定したポート>(以下の例の場合http://mockoon.mock.api:4011)でアクセスすることも可能でした。

version: "3.7"
services:
  app01:
    # ----- 略 -----
    environment:
      - EXTERNAL_API_HOST=mockoon.mock.api
      - EXTERNAL_API_PORT=4011
    networks:
      - default_network
  mock-server:
    image: mockoon/cli:5.1.0
    command: ["--data", "data"]
    ports:
      - 4011:4011
    volumes:
      - ./data/todo.json:/data:readonly
    networks:
      default_network:
        aliases:
          - "mockoon.mock.api"

networks:
  default_network:

感想

今回はprismmockoonを使ってモックサーバを構築しました。
どちらも簡単に作成できることがわかりました。

すでに OpenAPI を使用している場合はprismを使ったほうが効率的ですし、レスポンスの値を動的にしたい場合はmockoonのを選択するのが良いように感じます。

そのため、どちらにするかはそれぞれの開発のニーズによって選択するのが良いのかなと思いました。

Discussion