Json-serverの立ち上がり
json-serverインストール
- Step1 インストール
npm install json-server
- Step2 jsonファイルを用意(DBのようなもの)
package.json同じ階層の下に、mockと言うフォルダーを作成して、mockフォルダーの下にjsonファイルを作成
// mock/db.json
{
"menu": [
{ "id": 1, "name": "menuA" },
{ "id": 2, "name": "menuB" },
{ "id": 3, "name": "menuC" }
]
}
- Step3 jsonファイルとポートを指定して実行
npx json-server --watch mock/db.json --port 30001
\{^_^}/ hi!
Loading mock/db.json
Loading mock/route.json
Done
Resources
http://localhost:3001/menu
http://localhost:3001/menu でデータ取得ことが確認できる
- Step4 mockフォルダーの下にルーティングファイルを用意(Optional)
// mock/routes.json
{
"/api/menu": "/menu"
}
- Step5 モックサーバー起動コマンドをpackage.jsonのscripts下へ追加
"scripts": {
"json-server": "json-server --watch mock/data.json --port 3001 --routes mock/routes.json"
}
- Step6 package.jsonで追加されたモックサーバーの起動コマンドを実行
npm run json-server
\{^_^}/ hi!
Loading mock/db.json
Loading mock/route.json
Done
Resources
http://localhost:3001/menu
Other routes
/api/menu -> /menu
Home
http://localhost:3001
Type s + enter at any time to create a snapshot of the database
Watching...
http://localhost:3001/menu あるいはhttp://localhost:3001/api/menu で同じデータを取得ことが確認できる
上記よりモックサーバーが立ち上げたら、CRUDをテスト
- Getでデータを取得する
// 全件取得する
curl localhost:3001/menu
[
{
"id": 1,
"name": "menuA"
},
{
"id": 2,
"name": "menuB"
},
{
"id": 3,
"name": "menuC"
}
]
// Id指定で取得する
curl localhost:3001/menu/1
{
"id": 1,
"name": "menuA"
}%
- Postでレコードを追加する
curl -X POST localhost:3001/menu -d name=menuD
{
"name": "menuD",
"id": 4
}%
// 確認する
curl localhost:3001/menu
[
{
"id": 1,
"name": "menuA"
},
{
"id": 2,
"name": "menuB"
},
{
"id": 3,
"name": "menuC"
},
{
"name": "menuD",
"id": 4
}
]%
その時、mock/db.jsonの下にもmenuDが追加されました。
- PUTでレコードを更新する
curl -X PUT localhost:3001/menu/4 -d name=menuD-newName
{
"name": "menuD-newName",
"id": 4
}%
//確認する
curl localhost:3001/menu
[
{
"id": 1,
"name": "menuA"
},
{
"id": 2,
"name": "menuB"
},
{
"id": 3,
"name": "menuC"
},
{
"name": "menuD-newName",
"id": 4
}
]%
- Deleteでレコードを削除する
curl -X DELETE localhost:3001/menu/4
{}%
// 確認する
curl localhost:3001/menu
[
{
"id": 1,
"name": "menuA"
},
{
"id": 2,
"name": "menuB"
},
{
"id": 3,
"name": "menuC"
}
]%
エンドポイントごとにJsonファイルを分ける
json-serverの仕様上、サーバーが起動する時、データのjsonファイルは一つしか読み込めないため、開発を進めるうちに、モック用のデータjsonファイルも大きくなり過ぎてしまう。
下記のはエンドポイント毎にjsonファイルを分ける方法を紹介する。
エンドポイントごとにJsonファイルを分ける
例:今のdb.jsonファイルは下記のようになっている。
// mock/db.json
{
"menu": [
{
"id": 1,
"name": "menuA"
},
{
"id": 2,
"name": "menuB"
},
{
"id": 3,
"name": "menuC"
}
],
"customers": [
{
"id": 1,
"name": "Jack"
},
{
"id": 2,
"name": "Jim"
},
{
"id": 3,
"name": "Jhon"
}
],
"cards": [
{
"id": 1300157001,
"ctsId": 1,
"leval": "A"
},
{
"id": 1300157002,
"ctsId": 2,
"leval": "A"
},
{
"id": 1300157003,
"ctsId": 3,
"leval": "B"
}
]
}
- Step1 エンドポイント毎にjsonファイルを分ける
//mockフォルダーの下にdataフォルダーを作成し、エンドポイント毎にjsonファイルを作成
.
└── mock
└── data
├── menu.json
└── customers.json
└── cards.json
- Step2 mockフォルダーの下にdataフォルダーしたのjsonファイルを一つのdb.jsonへまとめるスクリプトファイルmergeDataToDb.cjsを作成する
// mock/mergeDataToDb.cjs
const fs = require('fs')
const path = require('path')
const outputFileName = 'db.json'
const root = path.resolve('./', 'mock')
const fixturesPath = root + '/data'
const json = {}
try {
fs.unlinkSync(root + '/' + outputFileName)
} catch (error) {
console.log('db.jsonファイル存在したいため、これから作成する')
}
fs.readdirSync(fixturesPath).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] = {}
json[endpoint] = JSON.parse(
fs.readFileSync(fixturesPath + '/' + file, 'utf-8')
)
}
}, {})
fs.writeFile(root + '/' + outputFileName, JSON.stringify(json), function (err) {
if (err) throw err
console.log('=== Create ' + outputFileName)
})
- 起動コマンドを修正
package.jsonと同じ階層でjson-server.jsonファイルを作成し、ポート番号、ルーティングなどを設定する
// json-server.json
{
"watch": true,
"routes": "mock/routes.json",
"port": 3001
}
mockフォルダーの下にjsonーserverの起動に関して起動スクリプトファイルindex.cjsを追加する
// mock/index.cjx
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('mock/db.json')
const middlewares = jsonServer.defaults()
const apiURL = require('./routes.json')
server.use(middlewares)
server.use(jsonServer.rewriter(apiURL))
server.use(router)
server.listen(3001, () => {
console.log('JSON Server is running')
})
package.jsonでのjsonーserver起動コマンドを修正する
// json-server.json
"scripts": {
"json-server":{
"json-server": "node mock/merge_data_to_db.cjs && node mock/index.cjs"
}
以上でエンドポイント毎にjsonファイルを分けました。
PostをGetとして扱う
開発段階で、モックAPIを使う時、リクエストはPOSTで、レスポンスはデータを取得する、つまりモックAPIはGetとして動作させる。その時、起動スクリプトファイルindex.cjsでmiddlewaresの下に下記の内容を追加すれば良い。
// mock/index.cjs
server.use(jsonServer.bodyParser)
server.use((req, res, next) => {
if (req.method === 'POST') {
req.method = 'GET'
}
next()
})