Mock Service Worker で開発用のモックAPIを作る
フロントエンドの開発時に仮の API を使いたいってシチュエーションはわりとあると思います。
そんな時に、Mock Service Worker を使うと便利だったのでまとめます。
Mock Service Worker とは?
Mock Service Worker は、ネットワークレベルで API リクエストをインターセプトして mock のデータを返すためのライブラリです。API リクエストを含む処理のテストや、開発時の mock サーバーの代替として利用出来ます。
テストでの利用については以前こちらの記事でまとめました。
今回は開発時のモック API としての利用について書きます。
開発用の API というと、JSON Serverが有名ですが、Mock Service Worker では Service Worker を使ってリクエストを返すため、別プロセスでローカルサーバーを立てる必要もなく手軽に利用できます。
仕組みは公式のこちらのビデオがわかりやすいです。
Mock Service Worker での開発用APIの立て方
Vite で作った Vue のプロジェクトで利用する場合を例にまとめます。
パッケージの追加
Mock Service Worker のパッケージをプロジェクトに追加します。
$ yarn add -D msw
Service Workerのコードを生成
Mock Service Worker は Service Worker で API リクエストをインターセプトします。その Service Worker のコードをプロジェクトの公開ディレクトリに追加します。
ファイルは Mock Service Worker の提供する CLI を使って生成できます。
$ npx msw init public/ --save
Vue プロジェクトの公開ディレクトリは./public
なのでそちらを指定しています。
コマンドを実行すると public 配下に mockServiceWorder.js
が追加されるはずです。
public/
├── favicon.ico
└── mockServiceWorker.js # 追加
mockServiceWorder.js
では、Service Worker でのイベント処理が書かれています。
モック API の定義を追加
プロジェクトの src 配下にmock
ディレクトリを作成し、そこにhandler.js
とbrowser.js
を追加します。
handler.js
では、どの URL のリクエストに対して、どのようなレスポンスを返すのかを定義しています。
import { rest } from 'msw'
export const handlers = [
rest.get('/users', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json([
{
id: 1,
name: 'foo',
},
{
id: 2,
name: 'bar',
}
]),
)
}),
]
browser.js
では handler.js
で作成した定義をもとに Service Worker のセットアップを行っています。
import { setupWorker } from 'msw'
import { handlers } from './handlers'
export const worker = setupWorker(...handlers)
Service Workerのスタート処理の追加
これまでの作業で準備が出来たので、プロジェクトのエントリーポイントに Service Worker のスタート処理を追加します。
Vue のmain.js
に追記する例です。
import { createApp } from 'vue'
import App from './App.vue'
if (process.env.NODE_ENV === 'development') {
const { worker } = require('./mocks/browser')
worker.start()
}
createApp(App).mount('#app')
開発ビルドの場合のみ、Worker を起動しています。
これでプロジェクトのスタート時にモックが動作するようになります。
モックの動作確認
実際にモックの動作を確認します。
App.vue に/users
の API を呼び出す処理を追加してみます。
<template>
<h1>Users</h1>
<ul>
<li v-for="user in users" :key="user.id">
id: {{user.id}}, name: {{user.name}}
</li>
</ul>
</template>
<script lang="ts">
import { ref, defineComponent, onMounted } from 'vue'
type User = {
name: string;
age: number
}
export default defineComponent({
name: 'App',
setup() {
const users = ref<User[]>([])
onMounted(async () => {
const res = await fetch('/users')
users.value = await res.json()
})
return { users }
}
})
</script>
yarn dev
で Vue の開発サーバーを起動し、localhost にアクセスし DevTools を開くと Console に Mocking enabled
と表示されるはずです。これが Mock Service Worker によるモックが動作していることを示します。
また、DevTools の Network を確認すると、Service Worker にインターセプトされた/users
へのリクエストが確認出来るはずです。
レスポンスを見ると handler.js
で定義した値が返却されています。
ページも問題なく描画されます。
参考
終わりに
以上、開発時の API リクエストのモック処理での Mock Service Worker の利用例でした。
別で開発サーバーのプロセスを立てるより、手軽にモックの API を使えるようになるのでとても良い感じだなと思いました。今後も使っていきたいです。
Discussion