JSON
docker
WireMock

DockerでAPIモックサーバを建てる

やりたいこと

外部API叩きたい -> モックサーバ欲しい
でも環境は汚したくない -> Docker
コーディングもしたくない -> WireMock(リクエストとそれに対応するレスポンスをjsonで定義)

準備

WireMockがインストールされてるイメージないかなと探したらありました。
DockerHub
GitHub
とりあえず動作検証として用意されてるサンプルを動かしてみる。
サンプルを取得
git clone https://github.com/rodolpheche/wiremock-docker.git
必要なものは以下wiremock-docker/samples/hello/stubs

stubs
├── __files
│   └── hello.json <- レスポンス(json)
└── mappings
    └── hello.json <- リクエストに対するレスポンス(body)を__files配下のファイルにマッピング。
                      ファイル名はリクエストに対応してなくてもおk。マッピング毎にファイル作れば見やすいね。

これをマウントしてコンテナ起動。イメージはalpine版の方が軽いだろうからタグで指定。
環境変数としてホストのuid渡してるのはアクセス権限云々っぽい。試しに渡さないと起動時に怒られた。
chmod 777 したら渡さなくておk

# samples/helloに移動して実行
$ docker port $(docker run -dP -v $PWD/stubs:/home/wiremock -e uid=$(id -u) rodolpheche/wiremock:2.14.0-alpine)
8080/tcp -> 0.0.0.0:32783
8081/tcp -> 0.0.0.0:32782
$ curl localhost:32783/hello
{
  "message": "Hello World !"
}

マウントしてるし__files配下のレスポンスファイルの中身を変更したら反映されるかなと思って試したらいけた。
mappings配下の方はというと無理だった。起動し直すとさすがに読み込まれた。
どんなマッピングしてるかの確認は下記で確認できる。
curl localhost:32783/__admin/

別コンテナからの参照

そもそもモックサーバのコンテナを立てようとしてる人は参照元もコンテナだったりする訳で、
さっきのrunコマンドをdocker-composeに落としこむ。
uid渡したい場合は、compose upする前に環境変数にセットしてそれを参照するように記述すればおk。

  hoge:
    #省略
    depends_on:
      - mockserver

  mockserver:
    image: rodolpheche/wiremock:2.14.0-alpine
    ports: 
      - "61212:8080"
    volumes:
      - ./wiremock/hello/stubs:/home/wiremock

こんな感じでcompose upしてhogeコンテナにアタッチしてcurl mockserver:8080/helloでレスポンス確認できる。
portsで設定してるのはホストから確認する時のポートだからなんでもおk。

マッピングの例

POSTで2つのパラメータが渡されてきたらhoge.jsonをレスポンスする。
マッチングしなかったら勝手に404のエラーコードを返してくれる。

{
  "request": {
    "method": "POST",
    "url": "/hoge/",
    "headers": {
      "Content-Type": {
          "matches": "application/x-www-form-urlencoded"
      }
    },
    "bodyPatterns" : [
      {
        "matches" : "(.*)username=(.*)"
      },
      {
        "matches" : "(.*)password=(.*)"
      }
    ]
  },
  "response": {
    "status": 200,
    "bodyFileName": "hoge.json"
  }