APIモックに便利なjson-serverをdockerを使って構築してみる

APIモックをサクッと構築したいなら、ゼロコーディングで30秒でできるという触れ込みの``json-server``がおすすめです。

https://github.com/typicode/json-server

``json-server``はnpmでインストールするのですが、開発マシンを汚したくないときには``docker``を使って構築したいなと思いますよね。ということで、dockerを使ってjson-serverを構築してみました。githubにサンプルコードをのせてあります。
https://github.com/kiyo27/json-server-docker

## Dockerfileを準備

ベースイメージにnodeを使用してnpmでjson-serverをインストールしています。コンテナ起動時にjson-serverをオプション付きで起動できるようにしているので、コンテナを立ち上げたらそのままjson-serverが利用できます。

```dockerfile
FROM node:latest

RUN npm install -g json-server

WORKDIR /data

EXPOSE 3000

ENTRYPOINT ["json-server"]

CMD ["--watch", "db.json", "--host", "0.0.0.0"]
```

## コンテナ起動

用意したDockerfileを使用してコンテナを起動します。

```bash
# ビルド
docker build -t json-server .

# 起動
docker run --name json-server -p 3000:3000 -v `pwd`/db:/data json-server
```

コンテナが起動できたら[http://localhost:3000](http://localhost:3000)を開いてトップページが表示されたら成功です。

![JSON-Server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780549/d5054ab8-95dd-2be3-fd5d-7974fd8dde84.png)


## 使い方

json-serverはGET, POST, DELETE, PUT, PATCHに対応しています。

### GET

```bash
$ curl -X GET http://localhost:3000/posts
[
  {
    "id": 1,
    "title": "json-server",
    "author": "typicode"
  },
  {
    "id": 2,
    "title": "new post",
    "author": "user"
  }
]
```

``id``を指定して取得もできます。パスパラメータを使用すると、配列ではなくオブジェクトで返却されます。

```bash
# クエリパラメータを使用
$ curl -X GET http://localhost:3000/posts?id=1
[
  {
    "id": 1,
    "title": "json-server",
    "author": "typicode"
  }
]

# パスパラメータを使用
$ curl -X GET http://localhost:3000/posts/1
{
  "id": 1,
  "title": "json-server",
  "author": "typicode"
}
```

``_embed``を使用すると子要素も指定して取得できます。

```bash
$ curl -X GET 'http://localhost:3000/posts?_embed=comments&id=1'
[
  {
    "id": 1,
    "title": "json-server",
    "author": "typicode",
    "comments": [
      {
        "id": 1,
        "body": "some comment",
        "postId": 1
      }
    ]
  }
]
```

### POST

POSTを使用して要素の追加もできます。

```bash
$ curl -X POST -H "Content-Type: application/json" -d '{"title":"third post","author":"user"}' http://localhost:3000/posts
{
  "title": "third post",
  "author": "user",
  "id": 3
}
```

追加されたデータは``db.json``に保存されます。

```json:db.json
{
  "posts": [
    {
      "id": 1,
      "title": "json-server",
      "author": "typicode"
    },
    {
      "id": 2,
      "title": "new post",
      "author": "user"
    },
    {
      "title": "third post",
      "author": "user",
      "id": 3
    }
  ],
  "comments": [
    {
      "id": 1,
      "body": "some comment",
      "postId": 1
    }
  ],
  "profile": {
    "name": "typicode"
  }
}
```

### PUT, PATCH

json-serverではデータの更新も可能です。

```bash
$ curl -X PUT -H "Content-Type: application/json" -d '{"title":"mod post","author":"user"}' http://localhost:3000/posts/3
{
  "title": "mod post",
  "author": "user",
  "id": 3
}
$ curl -X GET http://localhost:3000/posts?id=3
[
  {
    "title": "mod post",
    "author": "user",
    "id": 3
  }
]
$ curl -X PATCH -H "Content-Type: application/json" -d '{"title":"patch post","author"":"user"}' http://localhost:3000/posts/3
{
  "title": "patch post",
  "author": "user",
  "id": 3
}
$ curl -X  GET http://localhost:3000/posts?id=3
[
  {
    "title": "patch post",
    "author": "user",
    "id": 3
  }
]
```

### DELETE

``DELETE``メソッドを使用すれば要素の削除ができます。

```bash
$ curl -X DELETE http://localhost:3000/posts/3
$ curl -X GET http://localhost:3000/posts
[
  {
    "id": 1,
    "title": "json-server",
    "author": "typicode"
  },
  {
    "id": 2,
    "title": "new post",
    "author": "user"
  }
]
```

JavaScriptを使用すればいろいろカスタマイズできますが、それはまた今度。