0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Json-server に関して

Posted at

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()
})

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?