프론트엔드 개발을 하면서 API통신을 해야하는 경우가 많습니다. 하지만 실제 백엔드 API를 기다리거나 백엔드 개발이 완료되지 않은 상황에서 프론트엔드 개발을 진행해야 할 때 문제가 발생할 수 있습니다. 이런 상황에서 MSW(Mock Service Worker)를 사용하면 가상의 API 서버를 만들어서 API 통신을 모킹할 수 있습니다. 이를 통해 백엔드와의 의존성을 줄이고 독립적으로 개발을 진행할 수 있습니다. 또한 MSW는 테스트 작성이 용이하고, 다양한 시나리오를 시뮬레이션하여 애플리케이션의 다양한 동작을 테스트할 수 있습니다. 따라서 MSW는 프론트엔드 개발에서 개발 생산성을 높이고 테스트를 간편하게 수행할 수 있는 유용한 도구입니다.
MSW를 설치하려면 프로젝트의 디렉토리에서 다음 명령어를 실행합니다.
npm install msw --save-dev
// 또는
yarn add msw --dev
위 명령어를 실행하면 프로젝트에 MSW가 설치됩니다.
먼저, Service Worker를 등록해야 합니다. 아래 명령어를 실행하여 Service Worker를 등록할 수 있습니다.
npx msw init public/ --save
위 명령어를 실행하면 public
디렉토리에 Service Worker 파일이 생성됩니다.
이제 등록된 Service Worker를 사용하여 MSW를 활성화해야 합니다. 이를 위해 프로젝트의 진입접 파일인 index.tsx
에서 다음 코드를 추가합니다.
import ReactDOM from 'react-dom/client';
import App from './App';
import './styles/index.css';
import { worker } from './mocks/worker';
worker.start();
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />);
위 코드에서는 worker.start()
를 호출하여 worker
를 실행하고, 애플리케이션을 렌더링하기 전에 MSW를 활성화합니다.
먼저, API 응답에 필요한 데이터의 타입을 정의해야 합니다. 저희는 주로 카페 정보를 다루기 때문에 아래와 같이 Cafe
타입을 정의하였습니다.
// types.ts
export type Cafe = {
id: number;
title: string;
address: string;
images: string[];
like: number | null;
likeCount: number;
detail: {
available: string;
addressUrl: string;
etc: string;
};
};
다음으로, 모킹에 사용할 가짜 데이터를 생성해야 합니다. 저희는 Cafe
타입을 사용하여 cafes
배열을 생성하였습니다. 각 요소는 가짜 카페 정보를 나타내는 객체입니다.
// mockData.ts
import { Cafe } from '../types';
export const cafes: Cafe[] = [
{
id: 1,
title: '성수 카페',
address: '성수로 1길',
images: ['/images/cafe-image-1.png', '/images/cafe-image-1.png'],
like: 1,
likeCount: 1,
detail: {
available: '이건 어떻게 줄까 ?',
addressUrl: 'https://map.kakao/~~',
etc: '우리 카페는 이뻐용',
},
},
{
id: 2,
title: '성수 카페2',
address: '성수로 2길',
images: ['/images/cafe-image-2.png', '/images/cafe-image-2.png'],
like: null,
likeCount: 0,
detail: {
available: '이건 어떻게 줄까 ?',
addressUrl: 'https://map.kakao/~~',
etc: '우리 카페는 귀여워용',
},
},
{
id: 3,
title: '성수 카페3',
address: '성수로 3길',
images: ['/images/cafe-image-3.png', '/images/cafe-image-3.png'],
like: null,
likeCount: 0,
detail: {
available: '이건 어떻게 줄까 ?',
addressUrl: 'https://map.kakao/~~',
etc: '우리 카페는 귀여워용',
},
},
{
id: 4,
title: '성수 카페4',
address: '성수로 4길',
images: ['/images/cafe-image-4.png', '/images/cafe-image-4.png'],
like: null,
likeCount: 0,
detail: {
available: '이건 어떻게 줄까 ?',
addressUrl: 'https://map.kakao/~~',
etc: '우리 카페는 귀여워용',
},
},
{
id: 5,
title: '성수 카페5',
address: '성수로 5길',
images: ['/images/cafe-image-5.png', '/images/cafe-image-5.png'],
like: null,
likeCount: 0,
detail: {
available: '이건 어떻게 줄까 ?',
addressUrl: 'https://map.kakao/~~',
etc: '우리 카페는 귀여워용',
},
},
];
MSW에서는 handlers
를 사용하여 API 요청에 대한 응답을 정의합니다. 먼저 rest
와 cafes
를 임포트하여 handlers
배열을 생성하였으며, rest.get
메서드를 사용하여 /cards
경로로 들어오는 GET요청에 대한 응답을 정의할 수 있습니다.
// handlers.ts
import { rest } from 'msw';
import { cafes } from '../data/mockData';
export const handlers = [
// 카페 조회
rest.get('/cards', (req, res, ctx) => {
return res(ctx.status(200), ctx.json(cafes));
}),
];
마지막으로, worker
를 생성하여 핸들러를 등록합니다. 아래의 코드처럼 handlers
를 사용하여 worker
를 생성하였습니다.
// worker.ts
import { setupWorker } from 'msw';
import { handlers } from './handlers';
export const worker = setupWorker(...handlers);
위 코드에서는 setupWorker
함수를 사용하여 worker
를 생성하였습니다. handlers
배열을 전달하여 핸들러를 등록합니다.
이제 yarn start
명령어를 실행하여 프로젝트를 시작하면 MSW를 통해 API 모킹이 작동하는지 확인 할 수 있습니다. 또한 MSW를 사용하여 프론트엔드 개발을 더욱 효율적으로 진행할 수 있습니다.