17
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

爆速構築!json-serverでMock API

Last updated at Posted at 2020-05-15

はじめに

フロントエンド開発のためにAPIのモックが必要になったので、json-serverを利用してモックサーバを構築していきます。

基本的な環境構築

初期化

powershell
# プロジェクトディレクトリを作成し, 移動する
mkdir mock-api
cd ./mock-api

# 初期化処理
npm init -y

json-server

今回のメインとなる json-server を導入します。

powershell
npm i -D json-server

contents.json

エンドポイントとなる json ファイルを作成します。

powershell
mkdir api
new-item api/contents.json

作成した contents.json を編集します。
ここで編集した内容がAPIのレスポンスとして返されるようになります。

contents.json
{
    "contents": [
        {
            "id": 1,
            "title": "title - foo",
            "body": "body - bar",
            "author-id": 1
        },
        {
            "id": 2,
            "title": "title - foo2",
            "body": "body - bar",
            "author-id": 1
        },
        {
            "id": 3,
            "title": "title - bar",
            "body": "body - bal",
            "author-id": 2
        }
    ]
}

package.json

package.json を更新します。

package.json
{
  "name": "mock-api",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    ### ↓↓↓↓↓ ここから追加 ↓↓↓↓↓ ###
    "json-server": "json-server --watch ./api/contents.json --port 5000"
    ### ↑↑↑↑↑ ここまで追加 ↑↑↑↑↑ ###
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "json-server": "^0.16.1"
  }
}

実行

npm run コマンドで実行します。

powershell
npm run json-server

実行されると、以下にGET通信することで先ほどのcontents.jsonの内容が得られます。

http://localhost:5000/contents

応用的な環境構築

エンドポイントを複数用意したい場合

エンドポイントを複数用意したい場合、contents.jsonにもう一つ要素を追加することで解決します。

contents.json
{
    "contents": [
        {
            "id": 1,
            "title": "title - foo",
            "body": "body - bar",
            "author-id": 1
        },
        {
            "id": 2,
            "title": "title - foo2",
            "body": "body - bar",
            "author-id": 1
        },
        {
            "id": 3,
            "title": "title - bar",
            "body": "body - bal",
            "author-id": 2
        }
    ],
    "authors": [
        {
            "id": 1,
            "name": "hoge"
        },
        {
            "id": 2,
            "name": "fuga"
        }
    ]
}

上記のように編集し実行すると、以下のように通信先を切り替えることができます。

http://localhost:5000/contents
http://localhost:5000/authors

エンドポイント毎にファイルを分割したい場合

しかし、APIの規模が大きくなってくると単一ファイルではメンテナンスが難しくなってくることは想像に難しくありません。
そうなると「エンドポイント毎にファイルを分割したい」という欲求が生まれてきます。

そこで問題となってくるのが json-server の「単一ファイルしか受け付けない」という仕様です。
なので、今回は複数ファイルを一つにマージすることで対応したいと思います。

【参考】
  - Json-serverでモックAPI

(1) まず、マージをするためのスクリプトを用意します

powershell
mkdir scripts
new-item merge.js
scripts/merge.js
const path = require("path");
const fs = require("fs");

const root = path.resolve("./", "api");
const update = () => 
{
    const api = fs.readdirSync(root).reduce((api, file) => {
      if (api === undefined)
        api = {};
    
      if (path.extname(file) == ".json") {
        const endpoint = path.basename(file, path.extname(file));
    
        if (api[endpoint] === undefined)
          api[endpoint] = {};
    
        api[endpoint] = JSON.parse(fs.readFileSync(root + "/" + file, "utf-8"));
        return api;
      }
    }, {});
    
    fs.writeFile(root + "/../merged.json", JSON.stringify(api), err => {
      if (err)
          throw err;
    });
}

// 初回作成
update();

// jsonファイルを監視し, 監視ファイルに更新があるたびmerged.jsonを更新
fs.watch(root, (e, filename) => update());

(2) json-servermerge.js を両方同時に動作させるために npm-run-all を導入します

powershell
npm i -D npm-run-all

(3) package.json を更新します

package.json
{
  "name": "mock-api",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    ### ↓↓↓↓↓ ここから追加・更新 ↓↓↓↓↓ ###
    "json-server": "json-server --watch merged.json --port 5000",
    "merge": "node ./scripts/merge.js",
    "serve": "npm-run-all -p merge json-server"
    ### ↑↑↑↑↑ ここまで追加・更新 ↑↑↑↑↑ ###
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "json-server": "^0.16.1"
  }
}

(4) contents.jsoncontents.jsonauthors.json に分割します

powershell
new-item api/authors.json
contents.json
{
    "contents": [
        {
            "id": 1,
            "title": "title - foo",
            "body": "body - bar",
            "author-id": 1
        },
        {
            "id": 2,
            "title": "title - foo2",
            "body": "body - bar",
            "author-id": 1
        },
        {
            "id": 3,
            "title": "title - bar",
            "body": "body - bal",
            "author-id": 2
        }
    ]
}
authors.json
{
    "authors": [
        {
            "id": 1,
            "name": "hoge"
        },
        {
            "id": 2,
            "name": "fuga"
        }
    ]
}

(5) 以下のコマンドで実行します

powershell
npm run serve

これで複数ファイルに分割定義することが可能となります。

POSTやPUTでもレスポンスを受け取りたい場合

json-serverGET以外 のリクエストだと思ったようにレスポンスを返してくれないので、処理をフックして GET通信 に偽装します。

【参考】
  - json-server で使い捨てモックサーバを作る
  - JSON Serverを使ってGETとPOSTでレスポンスを変えてみた

(1) まず、処理をフックするためのスクリプトを追加します

powershell
new-item ./scripts/middleware.js
middleware.js
module.exports = (req, res, next) =>
{
    if(req.method == 'POST') {
        req.method = 'GET'      // GETに偽装
        req.query = req.body
    }
    next()
}

(2) package.json を更新します

以下では、--middlewares オプションを追加しています。

package.json
{
  "name": "mock-api",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    ### ↓↓↓↓↓ ここから更新 ↓↓↓↓↓ ###
    "json-server": "json-server --watch merged.json --port 5000 --middlewares ./scripts/middleware.js",
    ### ↑↑↑↑↑ ここまで更新 ↑↑↑↑↑ ###
    "merge": "node ./scripts/merge.js",
    "serve": "npm-run-all -p merge json-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "json-server": "^0.16.1"
  }
}

これでPOST通信でもjsonレスポンスを得ることができます。

APIのrouteをカスタムしたい場合

現状、APIのrouteが http://localhost:5000/{jsonファイル名} となっているため、これを http://localhost:5000/api/v1/{jsonファイル名} となるように変更してみたいと思います。

【参考】
  - Json-serverでモックAPI

(1) まず、routes.json を追加します

powershell
new-item ./routes.json
routes.json
{
  "/api/v1/*": "/$1"
}

(2) package.json を更新します

以下では、--routes オプションを追加しています。

package.json
{
  "name": "mock-api",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    ### ↓↓↓↓↓ ここから更新 ↓↓↓↓↓ ###
    "json-server": "json-server --watch merged.json --port 5000 --routes ./routes.json --middlewares ./scripts/middleware.js",
    ### ↑↑↑↑↑ ここまで更新 ↑↑↑↑↑ ###
    "merge": "node ./scripts/merge.js",
    "serve": "npm-run-all -p merge json-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "json-server": "^0.16.1"
  }
}

これで**http://localhost:5000/api/v1/{jsonファイル名}**でアクセスできるようになります。

おわりに

さらに詳しくは 公式サイト をご参照ください。

17
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?