[キャッチアップ] MSW
概要
- MSW を使った API モックを雑に試す
- Vite で立ち上げた Vue3 アプリケーションを使ってる
MSW について
MSW (Mock Service Worker) は、 ネットワークレベルで API をモックするための npm パッケージ。
ネットワークレベルというのが特徴で、利用側がモックの存在を意識せずとも、そのままのコードで API レスポンスだけを差し替えることができる。
利用側のコードを書き換える必要がないため、一つのモックで、開発環境、テスト環境、あるいは Storybook のようなサンドボックス環境でもそのまま利用することができる
素振り用のアプリを用意する
今回は、Vueアプリケーションの開発環境上で、サーバサイドが未完成のため、MSW によるモックを用いた開発をするという想定で試してみる。
単に素振り用 Vue アプリケーションがあれば充分なので、 Vite
で開発環境を用意する。
$ yarn create @vitejs/app msw-test --template vue-ts
開発環境をセットアップして立ち上げる。必要なパッケージをついでに追加しておく。
$ cd msw-test
$ yarn install
$ yarn add axios
$ yarn add -D prettier
$ yarn dev
スキャフォールドされた App.vue
を最低限の内容に書き換える
<template>
<div>Hello, MSW!!</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "App",
});
</script>
これで準備OK
MSW のインストール
msw は開発、テスト用途なので devDependencies でインストール
$ yarn add -D msw
REST API のモックを作成する
msw は、 REST API または GraphQL API のモックを作成することができるが、本スクラップでは REST のみを扱う。
src/mocks/handlers.ts
を作成し、ここに全てのモックの定義をまとめて書いていく。
import { rest } from 'msw'
export const handlers = [
rest.get('/users', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
users: [
{
id: 1,
name: 'suzuki'
},
{
id: 2,
name: 'sato'
}
]
})
)
})
]
直感的に読めると思うが、ここでは /users
にGET リクエストした際に、ステータスコード200で、2種類のユーザー情報を返却するようなモックを定義した
モックを ブラウザから利用する
モックの定義が完了したので、次はこれをブラウザ上で Service Worker
を使って動かしていく。
なお、 MSW は Node 上でも動かすことが出来るが、 Node では Service Worker
が使えないため、別の方法を用いることになるが、ここではブラウザ上でのみ動作確認を行う。
ワーカーのセットアップ
ここで立ち上げる Service Worker
は、ブラウザ上でのリクエストを仲介し、モックレスポンスに差し替える役割を持つ。
そのために、ワーカーのコードを配置する必要があるが、これを自分で書くのは困難なので、 以下コマンドを用いて MSW から提供されるコードを複製する。
$ npx msw init public/ --save
これによって、 public/
ディレクトリに、ワーカーコードが作成される。 public/
ディレクトリはプロジェクトごとにパスが異なるが、ここでは Vite
を使って Vue アプリケーションのスキャフォールドをしているので、 public/
が公開用ディレクトリとなる。
ワーカーとモックの紐付け
handler.ts
と同じディレクトリに browser.ts
を作成し、 setupWorker
関数を用いて、ワーカーとモックハンドラを紐付ける。
import { setupWorker } from 'msw'
import { handlers } from './handlers'
export const worker = setupWorker(...handlers)
ワーカーを動かす
ワーカーの準備が整ったので、アプリケーション側のコードでワーカーを開始する
<template>
<div>Hello, MSW!!</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'App',
setup() {
if (process.env.NODE_ENV === 'development') {
import('./mocks/browser').then(module => {
module.worker.start()
})
}
}
})
</script>
コンソールに以下のメッセージが出れば成功
[MSW] Mocking enabled.
動作確認
App.vue
を修正し、ワーカーが立ち上がったら axios
で /users
を呼び出し、レスポンスを state に保存し、それをテンプレートで描画できるようにする。
<template>
<div>
<ul>
<li :key="user.id" v-for="user in state.users">
<p>id: {{ user.id }}</p>
<p>name: {{ user.name }}</p>
</li>
</ul>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
import axios from 'axios'
type User = { id: number; name: string }
export default defineComponent({
name: 'App',
setup() {
const state = reactive({
users: [] as User[]
})
if (process.env.NODE_ENV === 'development') {
import('./mocks/browser').then(async module => {
await module.worker.start()
const response = await axios.get('/users')
state.users = response.data.users
})
}
return { state }
}
})
</script>
モックされたユーザー一覧が描画されることが確認できた