1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

msw×Next.js(PageRouter)

Last updated at Posted at 2024-10-20

msw

APIリクエストをインターセプトしてモックデータを返したりすることができるパッケージです。
今回はREST API(Fetch APIを利用)想定で進めます。

src/mocks/handlers.js

// src/mocks/handlers.js
import { http } from 'msw'
 
export const handlers = [
  http.get('https://jsonplaceholder.typicode.com/todos/1', () => {
    console.log('Captured a "GET https://jsonplaceholder.typicode.com/todos/1" request')
  }),
  http.post('/posts', () => {
    console.log('Captured a "POST /posts" request')
  }),
  http.delete('/posts/:id', ({ params }) => {
    console.log(`Captured a "DELETE /posts/${params.id}" request`)
  }),
]

参照:https://mswjs.io/docs/network-behavior/rest

リクエストハンドラ

  http.get('/posts', () => {
    console.log('Captured a "GET /posts" request')
  }),

参照:https://mswjs.io/docs/network-behavior/rest

レスポンスリゾルバ

HttpResponse部分のこと

  http.get('/posts', () => {
    return HttpResponse.json(Array.from(allPosts.values()))
  }),

参照:https://mswjs.io/docs/network-behavior/rest

リクエスト本文を読み取る

request本文を読み取る
request.json()はPromiss型を返すためawaiが必要
request.json() は、リクエストのボディを JSON 形式として解析するためのメソッド

http.post('/posts', async ({ request }) => {
    const newPost = await request.json()

    allPosts.set(newPost.id, newPost)

    return HttpResponse.json(newPost, { status: 201 })
}),

参照:https://mswjs.io/docs/network-behavior/rest

パスパラメータの読み取り

リクエストパス内の1つのセグメント内でパラメーターを読み取る
「/posts/[任意の値]」があれば引っかかるようになる

  http.delete('/posts/:id', ({ params }) => {
    const { id } = params
 
    const deletedPost = allPosts.get(id)
 
    if (!deletedPost) {
      return new HttpResponse(null, { status: 404 })
    }
 
    allPosts.delete(id)
 
    return HttpResponse.json(deletedPost)
  }),

参照:https://mswjs.io/docs/network-behavior/rest

mockServiceWorker.js

npx msw init ./public --save

実行するとpackage.jsonに登録される。
mockServiceWorker.jsの保存先が登録され読み込みが行われる。

{
  "name": "my-app",
  "msw": {
    "workerDirectory": "./public"
  }
}

参照:https://mswjs.io/docs/cli/init

src/mocks/browser.ts

Browser integration

フロントサイドでモックサーバーを起動する

import { setupWorker } from 'msw/browser'
import { handlers } from './handlers'

export const worker = setupWorker(...handlers)

参照:https://mswjs.io/docs/integrations/browser

src/mocks/server.ts

Node.js integration

SSR

import { setupServer } from 'msw/node'
import { handlers } from './handlers'

export const server = setupServer(...handlers)

参照:https://mswjs.io/docs/integrations/node

pages/_app.tsx

フロントサイドかサーバーサイドかの判定が必要
これはmswのissueにも問題が上がってた対策です

開発環境のみで動くようにすることも必要(process.env.NODE_ENV)

if (process.env.NODE_ENV === 'development') {
  if (typeof window !== 'undefined') {
    import('../mocks/browser').then(({ worker }) => {
      worker.start()
    });
  }else{
    import('../mocks/server').then(({ server }) => {
      server.listen()
    });
  }
}

起動確認

npm run dev

これが出てきていればOK
スクリーンショット 2024-10-20 18.22.05.png

pages/index.tsx

index.tsxでインターセプトするURLをfetchで呼び出してみましょう

const test = async () => {

    await fetch("https://jsonplaceholder.typicode.com/todos/1");
    return;
};

コンソールログに結果が出ていればOK
スクリーンショット 2024-10-20 18.26.25.png

おまけ

今回はPageRouterなので検証していないが、appRouterの場合はこちらにexampleがあります(まだDraftですが・・・)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?