JSON Serverを使ってみる

JSON Serverを使ってダミーのAPIを用意して、フロントの実装を行ってみます。

設定方法

ターミナルでプロジェクトディレクトリに移動後、package.jsonを作成します。

npm init

プロジェクトディレクトリにJSON Serverをインストールします。

npm install json-server --save-dev

グローバルにインストールする場合は下記コマンドになります。

npm install -g json-server

プロジェクトディレクトリにdb.jsonというファイルを作成して、以下のような内容にします。

{
  "posts": [
    { "id": 1, "title": "記事A", "author": "suzuki" },
    { "id": 2, "title": "記事B", "author": "suzuki" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "suzuki" }
}

JSON Serverを起動します。

npx json-server db.json

グローバルにインストールした場合は下記になります。

json-server db.json

以下のように表示されたらOKです。

  \{^_^}/ hi!

  Loading db.json
  Done

  Resources
  http://localhost:3000/posts
  http://localhost:3000/comments
  http://localhost:3000/profile

  Home
  http://localhost:3000

  Type s + enter at any time to create a snapshot of the database
  Watching...

例えばブラウザで http://localhost:3000/posts にアクセスすると、以下のようなjsonが表示されるのが確認できます。

[
  {
    "id": 1,
    "title": "記事A",
    "author": "suzuki"
  },
  {
    "id": 2,
    "title": "記事B",
    "author": "suzuki"
  }
]

http://localhost:3000/posts/1 のように末尾にIDを指定することで、個別の値も取得できます。

{
  "id": 1,
  "title": "記事A",
  "author": "suzuki"
}

オプション

JSON Server起動時に設定できるオプションをいくつか試してみます。

db.jsonの監視

オプションでdb.jsonの監視を設定していないと、db.jsonを変更してもAPI側に反映されません。
監視の設定をしたい場合、起動時に–watchのオプションを追加します。

npx json-server --watch db.json

これでdb.jsonを変更した時にAPI側に反映されます。

静的ファイルの設置

JSON ServerはHTMLやCSS、jsなどの静的ファイルを設置することもできます。
プロジェクトディレクトリにpublicという名前のディレクトリを作成して、その中にindex.htmlを作成します。
JSON Serverを再起動して http://localhost:3000 にアクセスすると、public/index.htmlの内容が表示されます。

public以外のディレクトリ名にすることもできます。
例えばhtdocsディレクトリにしたい場合、JSON Serverの再起動時に指定を追加します。

npx json-server db.json --static ./htdocs

これでhtdocsディレクトリ内が静的ファイルとして使用できるようになります。

ルーティングの設定変更

現状ではdb.json内で設定した値に応じて「/posts」や「/posts/1」などのURLからAPIを使用できますが、このルールを変更することもできます。
プロジェクトディレクトリにroutes.jsonというファイルを作成して、例として以下のような内容にしてみます。

{
  "/api/*": "/$1",
  "/:resource/:id/show": "/:resource/:id",
  "/articles\\?id=:id": "/posts/:id"
}

ルートの設定は「/」で開始する必要があるのでご注意ください。

routes.jsonの設定を適用するため、以下コマンドで再起動します。

npx json-server db.json --routes routes.json

これで「/api/posts」にアクセスした場合には「/posts」と同じ内容が、「/api/posts/1」や「/posts/1/show」、「/api/posts/1/show」、「/articles?id=1」にアクセスした場合は「/posts/1」と同じ内容が表示されるようになりました。

設定ファイル

ここまで設定したwatchやstatic、routesなどのオプションをまとめて設定することもできます。
プロジェクトディレクトリにjson-server.jsonというファイルを作成して、今までの設定をまとめてみます。

{
  "watch": true,
  "static": "./htdocs",
  "routes": "routes.json"
}

これでJSON Serverの起動時にオプションを追記しなくてもよくなりました。
以下コマンドで再起動を行い、設定が反映されていればOKです。

npx json-server db.json

フロントの実装

Fetch APIを使って、実際にAPIを使用する実装を試してみます。

GET

GETでpostsの一覧を取得してみます。

fetch('http://localhost:3000/posts', {
  method: 'GET'
})
.then(response => {
  return response.json();
})
.then(data => {
  console.log(data);
});

先ほどブラウザで試したように、「/posts/1」の形で個別の値も取得することもできます。
GETのデモページ

POST

POSTでpostsに追加してみます。

var data = {
  "title": "記事C",
  "author": "suzuki"
}
fetch('http://localhost:3000/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data)
})
.then(response => {
  return response.json();
})
.then(data => {
  console.log(data);
});

idは自動で付与されるようです。
POSTのデモページ

PUT

PUTで既存の内容を更新してみます。

var data = {
  "title": "記事A-PUT",
  "author": "suzuki"
}
fetch('http://localhost:3000/posts/1', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data)
})
.then(response => {
  return response.json();
})
.then(data => {
  console.log(data);
});

PUTは「/posts/1」のように個別の値に対して行います。
PUTのデモページ

PATCH

PATCHで既存の内容を部分的に更新してみます。

var data = {
  "title": "記事A-PATCH"
}
fetch('http://localhost:3000/posts/1', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data)
})
.then(response => {
  return response.json();
})
.then(data => {
  console.log(data);
});

PATCHのデモページ

DELETE

DELETEで既存の内容を削除してみます。

fetch('http://localhost:3000/posts/1', {
  method: 'DELETE'
})
.then(response => {
  return response.json();
})
.then(data => {
  console.log(data);
});

DELETEもPUTやPATCHと同様に、「/posts/1」のようにして個別の値に対して行います。
DELETEのデモページ

パラメータ

GETパラメータで使用できる項目をいくつか試してみます。
db.jsonを変更します。

{
  "posts": [
    { "id": 1, "title": "記事A", "author": "suzuki" },
    { "id": 2, "title": "記事B", "author": "suzuki" },
    { "id": 3, "title": "記事C", "author": "suzuki" },

    〜 略 〜

    { "id": 19, "title": "記事S", "author": "suzuki" },
    { "id": 20, "title": "記事T", "author": "suzuki" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "suzuki" }
}

Filter

項目名と値を指定して、一致する内容を出力します。

http://localhost:3000/posts?title=記事A

この場合、titleが記事Aの内容のみ出力されます。

[
  {
    "id": 1,
    "title": "記事A",
    "author": "suzuki"
  }
]

同じ項目を複数指定することもできます。

http://localhost:3000/posts?id=1&id=2

この場合、idが1か2の内容のみ出力されます。

[
  {
    "id": 1,
    "title": "記事A",
    "author": "suzuki"
  },
  {
    "id": 2,
    "title": "記事B",
    "author": "suzuki"
  }
]

Paginate

_pageと_limitでページ分割ができます。

http://localhost:3000/posts?_page=2&_limit=5

この場合、1ページあたり5件の分割で2ページ目なので、全体の6〜10件目の内容が出力されます。

[
  {
    "id": 6,
    "title": "記事F",
    "author": "suzuki"
  },
  {
    "id": 7,
    "title": "記事G",
    "author": "suzuki"
  },
  {
    "id": 8,
    "title": "記事H",
    "author": "suzuki"
  },
  {
    "id": 9,
    "title": "記事I",
    "author": "suzuki"
  },
  {
    "id": 10,
    "title": "記事J",
    "author": "suzuki"
  }
]

Sort

_sortと_orderで並び替えができます。

http://localhost:3000/posts?_sort=id&_order=desc

この場合、idの値を降順に並び替えて出力します。

[
  {
    "id": 20,
    "title": "記事T",
    "author": "suzuki"
  },
  {
    "id": 19,
    "title": "記事S",
    "author": "suzuki"
  },
  {
    "id": 18,
    "title": "記事R",
    "author": "suzuki"
  },

〜 略 〜

  {
    "id": 2,
    "title": "記事B",
    "author": "suzuki"
  },
  {
    "id": 1,
    "title": "記事A",
    "author": "suzuki"
  }
]

Slice

_startと_endで開始位置と終了位置(インデックス番号)を指定して、指定範囲のスライスができます。

http://localhost:3000/posts?_start=1&_end=3

この場合、2〜3件目の内容を出力します。

[
  {
    "id": 2,
    "title": "記事B",
    "author": "suzuki"
  },
  {
    "id": 3,
    "title": "記事C",
    "author": "suzuki"
  }
]

_limitで終了位置ではなく出力件数の指定もできます。

http://localhost:3000/posts?_start=2&_limit=3

この場合、3番目から3件分の内容を出力します。

[
  {
    "id": 3,
    "title": "記事C",
    "author": "suzuki"
  },
  {
    "id": 4,
    "title": "記事D",
    "author": "suzuki"
  },
  {
    "id": 5,
    "title": "記事E",
    "author": "suzuki"
  }
]

Full-text search

qで全文検索ができます。

http://localhost:3000/posts?q=F

この場合、「F」で検索した内容が出力されます。

[
  {
    "id": 6,
    "title": "記事F",
    "author": "suzuki"
  }
]

POSTで投稿日時を自動で追加する

カスタマイズの例として、POST時に投稿日時を自動で追加するようにしてみます。
プロジェクトディレクトリにserver.jsを作成して、以下のようにします。

const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()
 
server.use(middlewares)
 
server.use(jsonServer.bodyParser)
server.use((req, res, next) => {
  if (req.method === 'POST') {
    req.body.createdAt = Date.now()
  }
  next()
})

// routes.jsonの内容
server.use(jsonServer.rewriter({
  "/api/*": "/$1",
  "/:resource/:id/show": "/:resource/:id",
  "/articles\\?id=:id": "/posts/:id"
}))

server.use(router)
server.listen(3000, () => {
  console.log('JSON Server is running')
})

10〜12行目部分でPOST時の内容にcreatedAtという項目名で投稿日時を追加しています。
16〜21行目はroutes.jsonを設定したい場合に適宜追記ください。

これで準備ができましたので、JSON Serverを再起動します。
その際、server.jsを使用するため下記コマンドを実行して起動します。

node server.js

これでPOSTを試してみたところ、投稿日時をタイムスタンプの形で追加することができました。

POSTをGETとして扱う

ダミーのAPIとして使用する際、POST時にデータの追加ではなく取得(GET)として動作させたいということがあったので、先ほどの例を変更してみます。
server.jsを以下のように変更します。

const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()
 
server.use(middlewares)
 
server.use(jsonServer.bodyParser)
server.use((req, res, next) => {
  if (req.method === 'POST') {
    req.method = 'GET';
  }
  next()
})

// routes.jsonの内容
server.use(jsonServer.rewriter({
  "/api/*": "/$1",
  "/:resource/:id/show": "/:resource/:id",
  "/articles\\?id=:id": "/posts/:id"
}))
 
server.use(router)
server.listen(3000, () => {
  console.log('JSON Server is running');
})

変更点は10〜12行目部分のみで、methodがPOSTだった場合にGETに置き換えています。

JSON Serverを再起動してPOSTを試してみたところ、データの追加ではなく取得することができました。

他にも設定できる項目が色々ありますので、詳しくは公式のドキュメントをご確認ください。

参考サイト

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2021年10月
 12
3456789
10111213141516
17181920212223
24252627282930
31