혼자 적어보는 노트

[Next.js] MSW로 API 모킹하기 본문

NextJS

[Next.js] MSW로 API 모킹하기

jinist 2022. 10. 13. 23:17

 

 

이전 프로젝트를 진행하며 예상한 날짜에 API가 완성되지 않거나 응답이 제대로 되지 않을 경우 작업에 딜레이가 생겼던 적이 있었다. 뒤늦게 MSW의 존재를 알게 되긴 했지만 그 때 도입하기엔 조금 늦은감이 있어서 적용을 못했었다.

그래서! 조금은 여유로운(?) 새로운 프로젝트를 진행하며 비슷한 상황이 생기는 듯 하여 MSW를 도입해보기로 했다.

 

MSW란?

MSW는 Mock Service Worker로 서비스 워커를 이용하여  API를 모킹할 수 있는 라이브러리이다.

서비스 워커는 서버로 요청이 발생하면 요청을 가로채서 MSW에 전달하고 handler에 정의해둔 응답을 받을 수 있다.

MSW를 사용하면 백엔드 API가 완성되지 않았을 때 API를 모킹하여 가상으로 데이터를 불러올 수 있기 때문에 미리 코드를 작성하고 이후 API가 완성되면 실제 API와 연결시킬 수 있다.

 

 

참고: https://github.com/vercel/next.js/tree/canary/examples/with-msw

 

GitHub - vercel/next.js: The React Framework

The React Framework. Contribute to vercel/next.js development by creating an account on GitHub.

github.com

 

MSW 도입

 

패키지 설치

npm install msw --save-dev
# or
yarn add msw --dev

 

핸들러 정의

src/mocks/handlers.ts 파일을 생성하여 요청에 대한 응답을 해주는 핸들러를 작성한다.

express와 비슷한 형태로 핸들러를 작성할 수 있다.

// handlers.ts

import { randomData } from './data';
import { rest } from 'msw';

export const handlers = [
  rest.get('/random', (req, res, ctx) => {
    return res(ctx.json(randomData));
  }),
];

 

브라우저 환경 설정

// src/mocks/browser.ts

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

export const worker = setupWorker(...handlers);

 

노드 환경 설정

// src/mocks/server.ts

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

export const server = setupServer(...handlers);

 

msw 설정

src/mocks/index.ts 파일에서 서버와 브라우저 환경에서 다르게 동작하도록 설정을 한다.

// src/mocks/index.ts

if (typeof window === 'undefined') {
  const { server } = require('./server');
  server.listen();
} else {
  const { worker } = require('./browser');
  worker.start();
}

export {};

 

그리고 _app.tsx에서 src/mocks/index.ts에서 작성한 코드를 불러와서 실행시킬 수 있는데

mocking이 enabled일 때만 실행될 수 있도록 설정할 수 있다.

// _app.tsx

if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') {
  import('../mocks');
}

 

 

 

service Worker 생성

MSW에서 제공하는 CLI도구를 사용하여 서비스 워커 코드를 생성할 수 있다.

npx msw init public/ — save

위 명령어를 입력하면 public/mockServiceWorker.js 파일이 생성된다.

 

 

페이지에서 사용하기

페이지에서 기존 api요청과 동일한 방식으로 사용을 할 수 있다.

import { useEffect } from 'react';

const test = () => {
  const getRandom = async () => {
    const res = await fetch('/random').then(res=> res.json());
    console.log(res.data);
  };

  useEffect(() => {
    getRandom();
  }, []);

  return (
    <div>
      <button onClick={getRandom}>랜덤데이터 불러오기</button>
    </div>
  );
};

export default test;

 

 

개발자 도구에서 확인하기

Network 탭의 응답 헤더를 통해 msw에서 응답을 받은 것을 확인할 수 있다.

 

애플리케이션 탭의 Service Workers에서 현재 실행중인 서비스 워커를 확인할 수 있다.

 

 


+ 에러

Module not found: Error: Can't resolve '@mswjs/interceptors/lib/interceptors/ClientRequest' in '/home/ntucker/src/rest-hooks/website/node_modules/msw/lib/node'
Did you mean 'index.js'?

 

https://github.com/mswjs/msw/issues/1267#1399

 

Can't resolve '@mswjs/interceptors/lib/interceptors/ClientRequest' · Issue #1267 · mswjs/msw

Prerequisites I confirm my issue is not in the opened issues I confirm the Frequently Asked Questions didn't contain the answer to my issue Environment check I'm using the latest msw versio...

github.com

최신버전의 msw를 설치했는데 위와같은 에러가 발생하여 문제를 해결해보려했지만 모듈 내부를 수정해야 할 듯했고,

관련 문제가 아직 처리되지 않은듯 했다.

 

버전을 낮추어서 설치하여 아직은 문제없이 사용이 되기는 하나 맞는 해결 방법인지는 모르겠다.😅

 

 

 

 

Comments