API 통신은 필수적인 요소이지만, 개발 초기 단계에서는 백엔드 API가 준비되지 않았거나 외부 API와의 연결이 어려운 경우가 종종 발생합니다. 이런 상황에서 유용하게 활용할 수 있는 도구가 바로 Mock Service Worker(MSW)입니다.
Mock Service Worker(MSW)는 브라우저와 Node.js 환경에서 API 요청을 모킹할 수 있도록 도와주는 라이브러리입니다. Service Worker를 활용하여 네트워크 요청을 가로채고, 원하는 응답을 반환하는 방식으로 동작합니다.
$ npm install --save-dev msw
src/mocks 폴더 생성
import { rest } from 'msw';
export const handlers = [
rest.get('/api/endpoint', (req, res, ctx) => {
return res(ctx.status(200), ctx.json({ msg: '모킹된 메시지' }));
}),
];
import { setupWorker } from 'msw';
import { handlers } from './handlers';
export const worker = setupWorker(...handlers);
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);
Express 서버를 설정해서 MSW 기반으로 네트워크 요청을 모킹합니다.
먼저, MSW의 createMiddleware를 통해 요청을 가로채는 로직을 통합하고, handlers 파일에서 정의된 핸들러로 모킹된 응답을 반환합니다.
또한, express.json() 미들웨어를 사용해서 들어오는 요청 본문을 JSON 형태로 파싱하고, CORS 미들웨어를 통해 클라이언트에서 해당 Express 서버로의 요청을 허용합니다.
import { createMiddleware } from '@mswjs/http-middleware';
import express from 'express';
import cors from 'cors';
import { handlers } from './handlers';
const app = express();
const port = 9090;
app.use(cors({ origin: 'http://localhost:3000', optionsSuccessStatus: 200, credentials: true }));
app.use(express.json());
app.use(createMiddleware(...handlers));
app.listen(port, () => console.log(Mock server is running on port: ${port}));
msw/node 패키지의 serupServer API를 통해 서버를 설정해서 Node.js 환경에서 네트워크 요청을 가로채고 처리할 수 있게 해줍니다.
import { setupServer } from "msw/node";
import { handlers } from "./handlers";
export const server = setupServer(...handlers);
Next.js 15 이전 버전은 전통적인 Node.js 서버 환경에 가까웠습니다. 이 시기에는 Express와 같은 서버를 사용해 직접 네트워크 요청을 처리하거나, Express 서버에서 API 요청을 가로채는 방식으로 MSW를 설정하는 것이 일반적이었습니다.
하지만 Next.js 15 이후에는 앱 디렉터리 구조와 Route Handlers가 도입되면서 서버와 클라이언트 코드의 분리가 더욱 명확해졌습니다. 이에 따라 Express와 같은 별도의 서버 설정이 불필요해졌고, Next.js의 내장 API 라우트를 사용해 간단히 서버 로직을 구현할 수 있게 되었습니다.
과거에는 @mswjs/http-middleware의 createMiddleware를 사용해 Express 서버와 통합하여 네트워크 요청을 가로채는 방식이 주로 사용되었습니다. 하지만, 다음과 같은 이유로 Next.js와 같은 Serverless 프레임워크에서는 createMiddleware 방식이 적합하지 않았습니다.
Express는 계속 실행되는 서버를 전제로 설계되었지만 Serverless는 HTTP 요청이 올 때마다 함수가 실행되고 끝나면 종료되고, Express 미들웨어는 요청 흐름 전체를 관리하는 방식이지만 Serverless는 각 요청이 독립적으로 처리됩니다. 또한 Serverless는 간단한 함수로 모든 요청을 처리하는 데 최적화되어있지만, createMiddleware 방식은 Express 같은 서버를 추가로 설정해야 해서 구조가 복잡하고, Serverless의 장점을 살리지 못합니다.
Serverless 환경과 클라이언트-서버 분리형 아키텍처와의 통합성을 높이기 위해, MSW는 setupServer API를 제공했습니다. setupServer 방식은 Node.js 런타임에서 동작하며, 별도의 Express 설정 없이도 네트워크 요청을 가로채 테스트와 모킹을 수행할 수 있습니다. 이를 통해 모던 프레임워크에서도 브라우저와 서버 환경 모두에서 동일한 핸들러를 손쉽게 사용할 수 있게 되었습니다.