Closed5

json-server x vercel で最速無料モックAPIサーバ構築

A KidA Kid

json-serverで作ったモックAPIサーバを公開ネットワークからでも使えるように、vercelにデプロイする。
微妙にいろいろハマったのでメモしておく。

A KidA Kid

JSON Serverを使ってAPIサーバ実装

npm --init でプロジェクト初期化。

npm i json-server@0.7.14 で json-server インストール。
json-server は v1 がまだベータ版だし、ちょっとインターフェースが変わっている感じなので、安定している v0.7.14 を使っておく。

db.json として レスポンスデータファイルを作成、プロジェクトルートに配置。
api/category1/resource1 のようなエンドポイントの場合、JSON上 category1 > resource1 のような階層構造で定義するとうまくいかなかったので、 category1_resource1 のようなキーで定義しておいてルーティング定義で書き換えることにする(違う方法もあるかも)

{
  "category1_resource1": {
    "foo1":"bar1"
  },
  "category1_resource2": {
    "foo2":"bar2"
  }
  "category2_resource1": {
    "foo3":"bar3"
  }
}

必要に応じてルーティング書き換えのための routes.json を作成、プロジェクトルートに配置。
ここでは、前述の事情のため、エンドポイントの階層を _ に書き換える。

{
    "/api/*/*": "/$1_$2",
}

package.json の script に以下を定義

  "scripts": {
    "start": "json-server -p 3000 --watch db.json --routes routes.json"
  }

npm run start で実行。
ブラウザから http://localhost:3000/api/category1/resource1 にアクセスしてみてレスポンスが表示されれば成功。

A KidA Kid

JSON Serverをvercelで動くようにする準備

vercelのアカウントがなければ作成しておく。

githubに公開リポジトリを作成(privateでもいけるんだったかも)。

api/server.js を作成し、以下のように定義する。
細かいハマりポイントがいろいろあった。

  • server.js は api 配下に置いておかないと、今のvercelだとうまくいかないっぽかった
  • db.json を参照するときに、 fs.readFileSync('db.json', 'utf-8'); だと参照できない
    • 公式を見ると path.join(process.cwd(), 'db.json') のようにしろと書いているんだけど、これだとダメだった
    • 結局 path.resolve(__dirname, '..', 'db.json') なら参照できたのでこれでいく
  • POSTでリソースを更新する必要がないなら、単に jsonServer.router(filePath) でもよさそう
const jsonServer = require('json-server');
const server = jsonServer.create();

const fs = require('fs');
const path = require('path');
const filePath = path.resolve(__dirname, '..', 'db.json');
const data = fs.readFileSync(filePath, "utf-8");
const db = JSON.parse(data);
const router = jsonServer.router(db);

const middlewares = jsonServer.defaults();
server.use(middlewares);
server.use(
    jsonServer.rewriter({
      "/api/*/*": "/$1_$2",
    })
);
server.use(router);
server.listen(3000, () => {
    console.log("listening on port: 3000");
});

module.exports = server;

プロジェクトルートに vercel.json を作成。
古いサンプルだと rewrites の代わりに routes が使われていたり、functions の代わりに builds が使われていたりする。
現行バージョンだと rewrites, functions を使うのが正しいっぽい。
参考)https://vercel.com/docs/projects/project-configuration

{
  "functions": {
    "api/server.js": {
      "memory": 1024,
      "includeFiles": "db.json"
    }
  },
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "api/server.js"
    }
  ]
}

package.json の script を以下のように変更し、ローカルでも動くことを確認しておく。

  "scripts": {
    "start-node": "node api/server.js"
  }
A KidA Kid

vercelにデプロイする

上記までの変更を github に push しておく。

vercel側で Add New ... > Project > Import Git Repository で連携してデプロイ。
詳細は割愛するが、vercel.jsonがあれば基本的に何もいじる項目はない。

注意としては、gitリポジトリのフォルダ構成として src/ の下に package.json やら vercel.json やらがある、みたいな場合は vercel の Settings > Root Directory に src を指定しておく必要がある。

デプロイされたら、そのドメインのパスでAPI GETとかしてみてレスポンスとれたらOK。

A KidA Kid

json-server で POST リクエストにも固定のレスポンスだけ返したい

json-server 自体は POST や PUT でのリソースに更新にも対応している。
逆にいうと、POST とか PUT とかしちゃうとリソースが更新されちゃうので、何もせず固定の { "result":"success" } みたいなレスポンスだけ返してほしい、という用途には使えない。

これをやりたければ、 server.js の中で単に API メソッドを POST -> GET に書き換えてやればいい。
参考)https://github.com/typicode/json-server/issues/453

// ~~(略)~~
server.use(function (req, res, next) {
    if (req.method === 'POST') {
        req.method = 'GET';
    }
    next();
})
server.use(router);
// ~~(略)~~
このスクラップは5ヶ月前にクローズされました