開発中に外部に接続せずにAPIを叩くためのモックサーバを使ってみました。
なんだか、単体テスト時にも起動させることが出来るみたいで、後々試してみたいと考えています。
今回使ってみたのは「Mock Service Worker」略称「MSW」です。
他に有名なモックサーバの「json-server」と違い、別プロセスで起動の必要がないこと、ネットワークリクエストをインターセプトして設定したデータをレスポンスとして送ることなどが特徴です。
導入
プロジェクト配下で以下を実行し、MSWを導入。設定ファイルを作成
$ npm i msw --save-dev
$ npm install
ブラウザでMSWを実行するための設定ファイルを作成
$ npx msw init public/ --save
プロジェクトのsrc配下にmocksディレクトリを作成します。
その中に、browser.ts, handlers.js を作成。
各ファイルの内容は以下です。
browser.tsはmswのインスタンスを生成するためのものです。
import { setupWorker } from "msw";
import { handlers } from "./handlers";
export const worker = setupWorker(...handlers);
handler.jsはリクエストハンドラの設定です。
エンドポイントやメソッド、モックデータなどなど。。。
今回は簡単に
/api-sample にGETメソッドでアクセスしたときに
{
"id": 1,
"name": "taro"
}
を返す設定です。
import { rest } from "msw";
export const handlers = [
rest.get("/api-sample", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({ id: 10, name: "taro" })
);
}),
];
API呼び出しを行うコンポーネントを作成します。
本記事では、ApiSample.tsxとして作成します。
import { FC } from "react";
import axios from "axios";
type userType = {
id: number;
name: string;
};
const ApiSample: FC = () => {
const callApi = async () => {
const url = "./api-sample";
const res = await axios.get(url);
const sampleData: userType = res.data;
console.log(sampleData);
};
return (
<>
<button onClick={callApi}>APIを呼出す</button>
</>
);
};
export default ApiSample;
最後に、アプリ内でMSWが使えるようにトップコンポーネント(main.tsx)で読み込みます。
開発時のみ読み込むものなので、以下のように記載します。
なお、本記事はviteで構成しているので読み替えを適宜お願いします。
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
if (import.meta.env.DEV) {
const { worker } = await import("./mocks/browser.ts");
worker.start();
}
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
動作確認
最後のお楽しみポイントですね。起動からデータの取得まで出来ていることを願いましょう。
$ npm run dev
開発者ツールを開いた状態でアプリにアクセスして、コンソールを見てみます。
以下のように「[MSW] Mocking enabled.」と出力されていれば、MSWの起動は成功しています。
今回はボタン押下時にAPIを呼出すようにしたので、ボタンを押してみます。
console.log()で出力が出来てますね。
念のため、ネットワークタブも見てみます
いいですね。望んだとおりに動作してくれています。
今回はここまでで終わりとします。
最後に
下記画像のように、「Ctrl」+「c」でアプリ停止後に永遠とServiceWorkerのエラーログが流れ続けるのだけはなんとかしたい(模索中)
該当のブラウザでタブを削除or別サイトに遷移する
という方法で一時しのいでいます。