MSW(Mock Service Worker)를 이용한 API mocking

SuJeong·2023년 11월 14일
0

FrontEnd 지식

목록 보기
2/3

프론트 개발을 하던 와중에 백엔드 API 개발속도와 맞지 않아 동시에 개발이 진행되게 되어 /public경로에 실제 API response의 json key-value값을 맞춰서 mock data를 만들어 mocking하는 식으로 UI를 만들었다.
그러던 중 MSW라는 API mocking하는 라이브러리를 알게되었다.

MSW(Mock Service Worker)란?

서비스 워커(Service Worker)를 사용하여 HTTP 네트워크 호출을 가로채는 API 모킹(mocking) 라이브러리

백엔드에서 받는 API인 척 실제 네트워크가 이루어지는 것 처럼 프론트엔드의 응답값을 주는 라이브러리이다.

실제 네트워크단에서 일어나기 때문에 axios의 호출하는 엔드포인트나 REST API를 실제 API로 바꿔기기 쉬우며 에러처리나 예외처리를 똑같이 수행할 수 있다는 점이 굉장히 매력적이다.

MSW 사용법

1. 라이브러리 설치하기

저는 yarn을 사용하므로 yarn 커맨드로 설치

yarn add msw --dev

2. Service worker 등록

아래 명령어를 통해 msw라이브러리를 실행시켜 public 폴더 위치에 worker를 등록한다.

npx msw init public/ --save

3. worker 설정

// src/mocks/browser.ts

import { handlers } from "@mock/handlers/handlers";
import { setupWorker } from "msw";

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

worker 인스턴스를 생성하고, 요청 핸들러를 정의한다.

4. worker 실행

// src/main.ts
import initMockAPI from '@mock/index.ts';
import ReactDOM from 'react-dom/client';
import { RecoilRoot } from 'recoil';
import App from './App.tsx';

initMockAPI();

ReactDOM.createRoot(document.getElementById('root')!).render(
  <RecoilRoot>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </RecoilRoot>
)
// src/mocks/index.ts
const initMockAPI = async (): Promise<void> => {
  if (import.meta.env.VITE_REACT_ENV === '2') {
    const { worker } = await import("@mock/browser");
    worker.start();
  }
};

export default initMockAPI;

가장 최상단 루트파일인 main.ts에 worker 실행 코드를 추가한다.
(나는 개발환경에서만 worker를 실행하기 위해 환경변수를 통해 실행을 제어했다.)

이제 yarn dev로 어플리케이션을 다시 실행시키면 콘솔에서 메세지가 뜨면서 활성화가 된다 !

5. 요청 핸들러 작성

그럼 이제 네트워크 호출을 가로챌 준비는 끝났고 어떤 요청을 했을 때 어떤 응답값을 받아야하는지에 대한 정보를 나타내는 요청 핸들러를 작성해주어야한다.

// src/mocks/handlers/handlers.ts

export const handlers = [
  rest.get('/result', (req, res, ctx) => {
    const DataEnc = req.url.searchParams.get('DataEnc');
    const pageNum = req.url.searchParams.get('pageNum');

    if (!DataEnc) {
      return res(ctx.status(301, 'dataenc값 없음'));
    }
    if (pageNum === '0') {
      return res(ctx.json(pageData_0));
    } else if (pageNum === '1') {
      return res(ctx.json(pageData_1));
    } else if (pageNum === '2') {
      return res(ctx.json(pageData_2));
    } else if (pageNum === '3') {
      return res(ctx.json(pageData_3));
    } else if (pageNum === '4') {
      return res(ctx.json(pageData_4));
    } else if (pageNum === '5') {
      return res(ctx.json(pageData_5));
    } else if (pageNum === '6') {
      return res(ctx.json(pageData_6));
    } else {
      return res(ctx.json(pageData_7));
    }
  })
]

rest객체를 사용하여 get, post, put, delete 등 API에 해당하는 http메소드들을 불러올 수 있다.

응답 해석기

req는 요청정보, req는 응답 정보, ctx는 status code, headers, body 등 응답값들을 지정한다.

query parameter

req.url.searchParams.get를 통해 URLsearchparams로 넘겨준 querystring을 가져올 수 있고 파라미터별 값 분기처리를 통해 로직을 구현한다.


postman을 통해 API response값의 key와 value의 형식만 지정해주면 되기 때문에 이제는 더이상 API에 구애받지 않고 프론트엔드 개발을 할 수 있었다 !!
mock data보다 초기 코드작성이 많고 진입장벽은 높았지만 host를 변경해줘야하거나 상태코드에 따른 로직을 구현할 수 없었던 단점을 보완할 수 있어서 너무 좋았고 실제 API통신과 흡사해서 UI 구현하는데 너무 편리했다 ✨

profile
Front-End Developer

0개의 댓글