Mock API?
Mock의 사전적인 의미를 알아보자.
mock : 거짓된, 가짜의, 모의의
사전적인 의미로 유추해본다면 Mock API란 실제 API가 아닌 가짜, 모의의 API이다. Mock API는 말 그대로 진짜인 API를 흉내 내 사전에 정의된 데이터를 단순하게 돌려주는 형태의 API이다. 그렇다면 왜 실제 API가 아닌 가짜 API를 사용해야 할까?
프론트엔드 개발의 현실
현재 필자는 프론트엔드 개발을 담당하고 있다. 나의 개발 경험을 바탕으로 생각해보면 실제 서비스가 개발되어 배포되기까지 여러 유관 부서와 협업을 하게 된다. 크게 기획 - 디자인 - 백엔드 - 프론트엔드 - QA 팀들과 협업을 진행하는데 여기서 백엔드, 프론트엔드를 주목해보자. 프론트엔드팀에서 작업을 시작할 때 작업에 필요한 모든 API가 제공된다면 베스트겠지만 실제 업무에서는 예기치 못한 상황들로 인해 API가 제공되지 않는 일이 빈번하게 발생한다. 프론트엔드팀에서 API가 개발되기까지 손가락만 빨 수 없지 않은가? 그래서 실제 API가 개발되기 전까지 API 명세서를 토대로 Mock API를 사용해 개발을 진행한다. 이렇게 되면 프론트엔드팀과 서버팀 업무를 병렬로 진행할 수 있기 때문에 서비스 개발 기간을 단축할 수 있다.
Mock API 장점/단점
장점
- 프론트엔드팀과 개발팀의 업무 병렬화로 개발 기간 단축
- 네트워크 지연 시간 설정, 요청 실패, 성공에 대한 테스트 용이
- 데이터베이스에 대용량의 데이터가 없을 때 대용량 데이터 테스트 용이 (Infinte scroll, Pagination 등)
- 테스트하기 까다로운 데이터를 쉽게 셋업할 수 있다. (운영자에 의해 제재된 사용자 등)
단점
- 지속적인 관리의 어려움, 어느 순간 관리를 위한 관리를 하게 될 수 있음
Mock API 구현 방법
Mock API를 구현하는 방법으로는 가장 간단하게 .json
파일을 직접 사용하는 것부터 직접 Mock 서버를 구축하거나 Postman을 이용한 방법, Mocking API 라이브러리를 사용하는 방법 등 여러 가지가 있다. 이번 포스팅에서는 MSW 라이브러리에 대해서 알아보자.
MSW(Mock Service Worker)
Service Worker?
서비스 워커는 웹에서 구동 중인 자바스크립트(메인 스레드)와는 다른 별도 스레드에서 동작하므로 메인 스레드의 동작을 가로막지 않는다. 서비스 워커를 통해 네트워크 요청을 가로채거나, 높은 연산 비용이 드는 작업을 수행, Push 알림 등에 활용할 수 있다.
MSW는 Mock API를 편리하게 제공해주는 라이브러리로 클라이언트(브라우저)에서 서버로 보낸 네트워크 요청을 가로채 사전에 정의한 Mock 데이터를 보낸다. 여기서 서버로 보낸 요청을 가로채는 역할과 사전의 정의한 데이터를 반환하는 역할을 하는 것이 서비스 워커다. 서비스 워커에 Mock API와 데이터를 등록한다. 여기서 주의할 점은 실제 API와 Mock API의 요청 주소는 같아야 한다.
MSW 사용
이번에 토이 프로젝트에서 Youtube Data API를 활용했는데, Youtube Data API는 호출 횟수 제한이 걸려있다. 개발 시 여러 번의 API를 호출해야 하는데 이럴 경우에도 Mock API를 활용할 수 있다. 토이프로젝트에 적용한 것을 기반으로 MSW 사용 방법에 대해 알아보자.
MSW 설치
1
$ npm install msw
디렉터리 구조
📦api
┗ 📜index.js
📦mocks
┣ 📜browser.js
┣ 📜data.js
┗ 📜handler.js
api
는 실제 API를 호출하는 함수가 위치하고, mocks
는 MSW를 이용하여 Mock API & Data를 정의하는 곳이다.
Mock 데이터 정의
mock/data.js
1
2
3
4
5
6
7
8
9
export const popularVideos = {
kind: "youtube#videoListResponse",
etag: "GW2fwi0ez98ra04BgX-pTHSx5A0",
items: [ /* ...videos */ ]
nextPageToken: "CBkQAA",
pageInfo: {
totalResults: 200,
resultsPerPage: 25,
},
실제 API에서 반환되는 데이터 구조랑 동일한 데이터를 정의한다.
MSW 핸들러 구현
mock/handler.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { rest } from "msw";
import { popularVideos } from "./data";
const BASE_URL = process.env.REACT_APP_BASE_URL;
export const handlers = [
rest.get(`${BASE_URL}/videos`, (req, res, ctx) => {
const isPopular = req.url.searchParams.get("chart") === "mostPopular";
const hasId = req.url.searchParams.get("id") && true;
if (isPopular) {
return res(ctx.status(200), ctx.json(popularVideos));
}
if (hasId) {
return res(ctx.status(200), ctx.json(video));
}
return res(ctx.status(500));
}),
];
Mock API를 정의하는 곳으로 실제 API와 동일한 구조(HTTP Method, URI)로 작성한다. 브라우저에서 handler.js
에 정의한 요청 주소로 API를 호출할 경우 해당 Mock API가 요청을 가로채 Mock 데이터를 반환한다. 브라우저가 여기에 정의되어 있지 않은 API를 호출할 경우 서비스 워커는 요청을 가로채지 않는다. 추가적으로 여기서 에러를 반환하거나 네트워크 지연 시간을 설정하는 등의 테스트를 진행할 수 있다.
MSW 서비스 워커 셋업
mock/browser.js
1
2
3
4
import { setupWorker } from "msw";
import { handlers } from "./handler";
export const worker = setupWorker(...handlers);
MSW 서비스 워커 구동
index.js
1
2
3
4
if (process.env.NODE_ENV === "development") {
const { worker } = require("./mocks/browser");
worker.start();
}
프로그램 시작 지점에 해당 코드를 넣는다. 개발 환경에서만 필요한 기능이기 때문에 개발 환경일 때만 서비스 워커를 구동하도록 설정한다.
MSW Mock API 통신 확인
개발자 도구의 Network 탭에서 (frome service worker)
를 확인할 수 있다.
느낀점
실무를 하다 보면 Mock API는 선택이 아닌 필수라고 생각한다. MSW를 사용했을 때 좋은 점을 정리해보면
- 별도 서버를 구축하지 않아도 된다.
- 내가 개발에 필요한 Mock API만 구현하고 나머지는 실제 API를 호출하기 편리하다.
- 프로젝트 저장소에 함께 관리할 수 있다.
- 프로젝트 코드에 변경이 없다. =
.json
을import
해서 사용하는 등의 코드가 필요 없다.