MSW 사용 방법
MSW는 가상의 백엔드가 존재하는 것처럼 네트워크 호출을 해주는 API 모킹 라이브러리이다.
MSW에서 브라우저를 통해 임의로 요청을 보내주고 응답을 받기 위해 브라우저에서 제공하는 서비스 워커가 필요하다.
서비스 워커란? 웹 표준 기술인 서비스 워커(Service Worker)는 브라우저로부터 나가는 요청이나 들어오는 응답을 중간에서 감시하거나 변조, 캐싱과 같은 작업들을 할 수 있게 도와준다. MSW는 이러한 서비스 워커의 능력을 이용해서 프론트에서 보내는 요청에 대해서 가상의 응답을 보내준다.
초기 설정
먼저 msw 패키지를 다운로드 받는다
npm i msw -D
msw에서 제공하는 다음의 명령어를 통해서 서비스 워커를 등록할 수 있다. 이 외에도 Node환경에서의 요청, 응답을 주고 받기 위해 따로
server.js
파일을 만들어 사용할 수도 있다(공식 문서 참조)npx msw init public/ --save
핸들러 함수 등록하기
MSW에서는 핸들러 함수를 통해서 요청 url과, 응답 JSON데이터 등을 정의할 수 있다.
현재는 RESTful Method를 통해 요청하기 때문에
rest
모듈을 가져와 다음의 방법으로 Mock를 정의할 수 있다.// src/mocks/handlers.js import { rest } from 'msw' export const handlers = [ // POST /login 요청 정의 rest.post('/login', (req, res, ctx) => { // Persist user's authentication in the session sessionStorage.setItem('is-authenticated', 'true') return res( // Respond with a 200 status code ctx.status(200), ) }), // GET /user 요청 정의 rest.get('/user', (req, res, ctx) => { // Check if the user is authenticated in this session const isAuthenticated = sessionStorage.getItem('is-authenticated') if (!isAuthenticated) { // If not authenticated, respond with a 403 error return res( ctx.status(403), ctx.json({ errorMessage: 'Not authorized', }), ) } // If authenticated, return a mocked user details return res( ctx.status(200), ctx.json({ username: 'admin', }), ) }), ]
현재 하나의 handlers 모듈안에 가상의 로그인과 사용자 정보 조회 API를 정의해 놓은 상태이다.
rest
모듈을 가져와서 POST, GET메소드를 사용하는 것처럼 작성할 수 있고, 콜백 함수의 각각의 인자를 통해서 응답과 응답 데이터의 헤더등을 설정할 수 있다.req
, an information about a matching request;
res
, a functional utility to create the mocked response;
ctx
, a group of functions that help to set a status code, headers, body, etc. of the mocked response.
이렇게 만들어진 핸들러함수는 서비스워커의 설정으로 넣어준다.
다음은 클라이언트 환경에서의 네트워크 호출을 위해
setupWorker
에 핸들러를 등록했다. 만약, 서버사이트 환경에서 msw 호출을 하고 싶다면 setupServer
를 사용한다.// src/mocks/broswer.ts import { setupWorker } from 'msw'; import { handlers } from './handlers'; // This configures a Service Worker with the given request handlers. export const worker = setupWorker(...handlers);
서비스 워커 컴포넌트에서 사용하기
설정을 완료한 서비스 워커는 컴포넌트에서
import
를 통해 사용할 수 있다.// Home page 'use client'; import { useEffect } from 'react'; export default function Home() { //client side에서 data mockAPI 호출 useEffect(() => { (async () => { const { worker } = await import('../mocks/browser'); worker.start(); const res = await fetch('/users'); const result = await res.json(); console.log('api result: ', result); })(); }, []); return ( <> <h1>Homepage</h1> </> ); }