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); });
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を試してみたところ、データの追加ではなく取得することができました。
他にも設定できる項目が色々ありますので、詳しくは公式のドキュメントをご確認ください。
コメントが承認されるまで時間がかかります。