カテゴリー
JSON ServerをCLIコマンドを使わずTypescript&node.jsからサーバーを立てるやり方
※ 当ページには【広告/PR】を含む場合があります。
2022/05/01
JSON Serverの利用者はあまりExpress.jsの利用方法に慣れていなくとも、色々な内部処理の実装をすることなくインストール一発で簡単にREST APIのテスト環境が整うことが最大の魅力です。
他方、より応用的なREST APIからのレスポンスを得ようとすると、JSON Serverをより深くカスタマイズする必要が出てきます。
場合に寄っては、Express.jsのミドルウェアを実装して利用することも検討しないといけません。
今回はそんなJSON Serverのカスタマイズのときに役に経つかもしれないTypescriptでの実装に焦点を当てます。
CLI有りのJSON Serverの利用手順をおさらい
通常のJSON Serverの使い方としては、node.jsのインストールされている環境で、CLIコマンドとしてグローバルにインストールし、
$ yarn global add json-server
さらにプロジェクトのルートフォルダに
db.json
{
"posts": [
{ "id": 1, "title": "json-server", "author": "typicode" }
],
"comments": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
このルートを定義した状態で、JSON Serverを以下のコマンドで起動します。
$ json-server --watch db.json
この間JSON Serverの利用者はほぼ何もソースコードを弄ることなく、REST APIのモック環境が出来上がります。
あとはクライアント側からこのサーバーがリスニングの状態のまま定義済みのルートにGETを投げてみると、
$ curl -XGET http://localhost:3000/posts/1
{ "id": 1, "title": "json-server", "author": "typicode" }
とJSON形式のレスポンスが得られます。
JSON Serverによって、ユーザーは殆ど何もすることなくフェイクのREST APIサーバーがローカルに構築することが可能です。
TypescriptでJSON Serverをカスタマイズしてみる
とりあえず先程のCLIからの使い方でも十分な開発水準で使えるのであれば、内部のソースコードを弄る作業はする必要ありません。
もっと柔軟かつ拡張的な機能をモックサーバーに持たせるのではあれば、Typescriptからサーバーをカスタマイズを検討してみるのも良いでしょう。
ここでいう拡張機能としては、リクエスト・レスポンスでの認証操作/バリデーションなどのHTTPインターセプトのようなものをミドルウェアとして介在させることを指します。
以下で、適当なtypescriptプロジェクトにJSON Serverと定義ファイルを導入します。
$ yarn add json-server -S
$ yarn add @types/json-server -D
まずはサーバーの本体になる
server.ts
import jsonServer from 'json-server';
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();
const endpoint = 'http://localhost:3000';
server.use(middlewares);
server.use(router);
server.listen(3000, () => {
console.log(`JSON Server is now running at ${endpoint}!`);
});
編集したら、早速tsビルドでトランスパイルして、出力されたjsコードが
dist/server.js
$ tsc
$ ls dist/
server.d.ts server.js server.js.map
この
server.js
$ node dist/server.js
JSON Server is now running at http://localhost:3000!
あとは別の端末からCurlなどでリクエストをすることでモックRest APIサーバーとして立ち上がります。
自作JSON Serverにミドルウェアを仕込む
よりJSON Serverを応用的にカスタマイズしていく場合、
server.ts
ここでのミドルウェアとは、Express.jsのミドルウェアそのものです。
必須ではないのですが、typescriptでより型の厳密に扱うために、プロジェクト環境に
express.js
$ yarn add express @types/express -D
なおExpress.jsのミドルウェアに関しては、このブログだけでは簡単に説明できるものではないので、より詳しく知りたい方は別の技術記事を探してみてください。
以下では実装のエッセンスだけを取り上げます。
まずは、typescriptプロジェクトのルートに
middleware
その
middleware
timeStamp.ts
import { Request, Response, NextFunction, RequestHandler } from 'express';
export function timeStamp(): RequestHandler {
return (req: Request, res: Response, next: NextFunction) => {
console.log('Now the time is ', Date.now());
//👇最終的にJSON Serverルーターに到達させるのに必要なnext
next();
}
};
Exress.jsの経験がある方ならば、慣れ親しんだ普通のExpressミドルウェアになります。
後はこのミドルウェアを
server.ts
import jsonServer from 'json-server';
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();
//👇ミドルウェアの呼び出し
import { timeStamp } from './middleware/timeStamp';
const myTimeStamp = timeStamp();
const endpoint = 'http://localhost:3000';
server.use(middlewares);
//👇ミドルウェアを利用する位置に注意
// (必ずrouterよりも前の位置で呼び出し)
server.use(myTimeStamp);
server.use(router);
server.listen(3000, () => {
console.log(`JSON Server is now running at ${endpoint}!`);
});
でtsトランスパイル後に、nodeでサーバーを立ち上げて、GETリクエストして挙動を確かめてみると、
$ node dist/server.js
JSON Server is now running at http://localhost:3000!
Now the time is 2022-04-29T03:16:21.828Z
GET /posts/1 200 11.158 ms - 85
ミドルウェアがきっちりと中間で仕事をしていることがわかります。
Typescriptでのルーターレスポンス出力の変形
JSON ServerでJSON形式のHTTPレスポンス部分を最終的に吐き出してくれる役目を担っているのが、
router(ルーター)
公式の利用説明の通りでJavascriptでの利用ならば、出力レスポンスは
router.render
router.render = (req, res) => {
res.jsonp({
body: res.locals.data
})
}
であったり、HTTPステータスコードも一緒に、
router.render = (req, res) => {
res.status(500).jsonp({
error: "error message here"
})
}
などとすると自由にレスポンス変形することができます。
これをTypescriptでやろうと思うと、執筆時現在で
@types/json-server
router.render
現状でこの不具合を回避するには以下のようにtypescriptコードをすると良いようです。
import jsonServer from 'json-server';
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();
const endpoint = 'http://localhost:3000';
server.use(middlewares);
server.use(router);
//👇routerを強制的にanyへアップキャストする
(router as any).render = (req: any, res: any) => {
res.jsonp({ data: res.locals.data })
}
server.listen(3000, () => {
console.log(`JSON Server is now running at ${endpoint}!`);
});
以上、TypescriptでJSON-Serverを拡張するテクニックを書き出してみましたが...ここまでREST APIサーバーを自作する必要があるのなら、
あくまでもJSON-Serverの売りはインストール後即時使えるREST APIフェイクサーバーですので、その内部のExpressコアの部分まで修正したいなら、いっそExpressから書き直した方が良いでしょう。
ここらへんの線引きは難しいので、どちらを使って開発を切り替えるかは己が判断で行ってください。
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー