ReactにMSWを導入する手順
現在参画中のプロジェクトでは、Mock Service Worker(以下「MSW」)というものを使用しています。フロントエンド開発時に、
「仮でもいいからAPI叩いてデータ取得したいなー」
って場面はあると思いますが、
そういった場合に便利だと思ったので、ざっくり使い方をまとめています。
公式サイトを参考にさせて頂きました。
インストール
Create React App
公式のドキュメントでは、Create React App アプリケーションに導入していく手順で書かれているので、まずはReactのアプリケーションを新規作成します。
npx create-react-app my-app
MSWをインストール
続いて、mswをインストールします。
npm install msw --save-dev
# or
yarn add msw --dev
モックの定義
どのリクエストをモックするかを定義するために、 リクエストハンドラ関数を使用します。
この関数を使うと、メソッドやURL、その他の条件に基づいて任意のリクエストを捕捉し、どういったレスポンスを返すかを指定することができます。
MSWを使う場合、リクエストハンドラやブラウザ、サーバ固有の設定などの一覧をモック定義と呼びます。
モック定義の管理に厳密なルールはありませんが、APIモック関連のモジュールは1つのディレクトリにまとめておくことが望ましいです。
ディレクトリを作成します。
mkdir src/mocks
ディレクトリを作成したら、すべてのリクエストハンドラを格納するモジュールを作成します。
touch src/mocks/handlers.js
APIを選択する
MSWでAPIをモックする方法は、実際のアプリケーションでAPIがどのように使用されるかに類似しています。
モックを作りたいAPIの種類に応じて、手順が変わります。
- REST API
- GraphQL API
今回は、 REST APIを選択します。
REST APIをモック化する
src/mocks/handlers.js
ファイルに、REST APIをモック化するために必要なものをインポートします。
これらは、ライブラリが公開しているrest
名前空間の下にまとめられています。
import { rest } from 'msw'
Request handlerを実装する
REST APIのリクエストを処理するには、そのメソッドとパス、そしてモック化されたレスポンスを返す関数を指定する必要があります。
ここではユーザーにおける基本的なログイン・フローをモック化していきます。
下記の2つのリクエストを処理します。
-
POST /login
:ユーザーがログインできるようにします。 -
GET /user
:ログインしているユーザーに関する情報を返します。
import { rest } from 'msw'
export const handlers = [
// /login へのPOSTリクエストを処理
rest.post('/login', null),
// /user へのGETリクエストを処理
rest.get('/user', null),
]
Response resolverを実装する
インターセプトされたリクエストに応答するには、レスポンス・リゾルバ関数を使ってモックレスポンスを指定する必要があります。
レスポンスリゾルバは、以下の引数を受け付ける関数です。
-
req
:一致するリクエストについての情報 -
res
:モックのレスポンスを生成するための関数ユーティリティ -
ctx
:ステータスコード、ヘッダ、ボディなどを設定するための関数群
上で定義したリクエストハンドラに対してレスポンスリゾルバを実装します。
import { rest } from 'msw'
export const handlers = [
rest.post('/login', (req, res, ctx) => {
// ユーザーの認証をセッションに永続させる
sessionStorage.setItem('is-authenticated', 'true')
return res(
// 200のステータスコードで応答する
ctx.status(200),
)
}),
rest.get('/user', (req, res, ctx) => {
// ユーザーが認証されているかどうかを確認する
const isAuthenticated = sessionStorage.getItem('is-authenticated')
if (!isAuthenticated) {
// 認証されていない場合、403エラーで応答する
return res(
ctx.status(403),
ctx.json({
errorMessage: 'Not authorized',
}),
)
}
// 認証された場合、模擬ユーザの情報を返す
return res(
ctx.status(200),
ctx.json({
username: 'admin',
}),
)
}),
]
統合する
ブラウザ環境とNode環境で同じリクエストハンドラを共有することができます。
NodeではService Workerを動かすことができないため、環境に応じて統合の仕方が異なります。
今回はブラウザ環境で動かします。
セットアップ
MSWは、リクエストのインターセプトを担当するService Workerを登録することで、クライアントサイドで動作します。しかし、Workerのコードを自分で書く必要はなく、ライブラリが配布しているWorkerファイルをコピーして使います。MSWは専用のCLIを提供しているので、それを使用します。
Mock Service Worker CLIのinit
コマンドを実行します。
npx msw init <PUBLIC_DIR> --save
<PUBLIC_DIR>
プレースホルダーを、公開ディレクトリへの相対パスに置き換えます。
Create React App プロジェクトでは、このコマンドは次のようになります。
npx msw init public/ --save
workerを設定する
モックの定義ディレクトリ(src/mocks
)に、Service Workerの設定と起動を行うファイルを作成します。
touch src/mocks/browser.js
browser.js ファイルで、上で定義したリクエストハンドラを使ってワーカーのインスタンスを作成します。
import { setupWorker } from 'msw'
import { handlers } from './handlers'
// 指定されたリクエストハンドラを持つサービスワーカーを設定する
export const worker = setupWorker(...handlers)
workerをスタートする
モック定義を実行するためには、アプリケーションのコードにインポートする必要があります。
モックは開発向けの技術なので、環境に応じて src/mocks/browser.js ファイルを条件付きでインポートする必要があります。
src/mocks/browser.js ファイルを、以下の例のように条件付きでインポートします。
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
if (process.env.NODE_ENV === 'development') {
const { worker } = require('./mocks/browser')
worker.start()
}
ReactDOM.render(<App />, document.getElementById('root'))
確認と検証
モック定義をインポートすると、ブラウザのコンソールにMSWからのアクティベーション成功のメッセージが表示されます。
これで定義されたハンドラにマッチするリクエストはインターセプトされ、モック化されるようになりました。
参考
まとめ
以上、MSWのをReactで使用する手順でした。
別のプロジェクトに参画した際など、状況に応じて導入してみたいと思います。
Discussion