MSW 적용 후기 (MSW를 적용하며! with(Vite, Ts, React, React-qery)

해진·2024년 4월 29일

돌아보며

목록 보기
2/7
post-thumbnail

어쩌다 도입하게 된거죠?

누군가 그렇게 이야기 하더군요...
front는 상체.. back은 하체라고...

장난같은 이 말은 다시 생각해보면 front는 펀치는 강하죠 그러나 걷지 못합니다...

front 개발자로 일을하며 매번 back-end 개발이 끝나야 front-end 개발을 들어갈 수 있다는 큰 불편함이 있습니다.

api가 개발이 된 후 해당 api를 통해서 작업을 진행해야합니다. 그러나 배포 기간은 다가오고 api개발의 속도는 더디고 이런 순간 정말 어찌하면 좋을지 휘몰아치며 개발과 QA를 했던 기억이 있습니다..

PM : **씨! 혹시 지금 작업이 어디까지 진행 된걸까요? test 서버에서 볼 수 있을까요?
나(프론트 개발자) : 아.. 지금 api가 완성되지 않아 디자인 구현 뿐이네요...

그 이후 해당 이슈를 꼭 해결해야겠다라고 마음을 먹고 이번 front-end 팀원 분들도 새로 오시게 되어 back-end의 작업기간 동안의 공백을 없애보자! 라는 목표로 MSW를 적용하게 되었습니다!
(msw 도입으로 위의 도표는 아래와 같은 시간 차트를 기대할 수 있습니다!)

back-end에게 api명세서를 전달받고 해당 내용에 대한 mock data를 활용하여 query문까지 작업할 수 있다는 것에서 정말 개발 시간을 효율적으로 쓸 수 있구나라고 감탄했습니다. (비동기가 주는 큰 이점이지요 하하)

MSW란?

MSW(Mock Service Worker)란 API Mocking 라이브러리입니다.

  • 서버로 향하는 네트워크의 요청을 가로챔
  • 모의 응답(Mocked Response)를 보내줌

크게 보면 위의 두가지의 기능을 수행합니다.


그렇다면 msw는 어떻게 네트워크 요청을 가로챌 수 있는 것일까?

=> 바로, Service Worker를 통해서 HTTP요청을 가로 챌 수 있습니다.

아래 그림을 통해 보다 쉽게 msw의 동작 원리를 파악 할 수 있습니다.

앱에서 요청하는 request가 직접 server까지 가는 것이 아닌 중간에 해당 요청을 MSW에서 가로채, 해당 요청과 일치하는 Mocked Response를 반환하게 됩니다.

  • 이런 MSW를 활용하게 된다면
기획 -> back-end 개발 -> front-end 개발

이었던 순서가

기획 -> back-end 개발 & front-end 개발

이렇게 변하게 될 것입니다. (사전 API 명세서 합의 필수!)

추가적인 MSW의 장점으로는 의도된 api에러를 만들어 낼 수 있다는 점입니다.

  • fallback 페이지를 구현하여 api의 response가 도착하지 않았을 때의 페이지 상태를 길게 보고싶다면 MSW를 통해 해당 상황을 충분히 만들어 낼 수 있다는 점입니다!
  • 비슷하게 다양한 에러 페이지 및 에러 처리 시의 상황 구현이 매우 쉬워진다는 장점도 있습니다!

MSW 세팅하기

https://mswjs.io/docs/getting-started
위 공식 문서를 살펴보면 MSW를 세팅하는 방식은 그다지 어렵지 않습니다.

npm install msw@latest --save-dev

터미널에서 위와 같은 문장으로 MSW를 설치합니다.

그 뒤 본인이 사용하는 REST 및 GraphQL API용 리소스를 활용해 모킹 시스템을 구현합니다.

저는 HTTP Request를 활용하여 해당 방법으로 설명을 진행하겠습니다.

최근(2023.10.23)에 msw 2.0 버전이 릴리즈 되었습니다.
해당 버전은 node 18이상부터 사용이 가능합니다.
(본인은 node v18.18.2 사용 중으로 msw 2.0을 사용하였습니다)

MSW 워크 스페이스 설정하는 법

[파일 구조]

data 폴더 안에는 mock data를 파일 형태로 만들어 두었습니다.
handlers 폴더 안에는 필요한 핸들러 함수를 만들었습니다.


handlers 를 따로 파일로 분리하여 작업 한 이유는 연관이 있는 api끼리 모아서 작업을 하는 것이 보다 깔끔하고 추후의 유지보수 측면에서도 이점이 있을 것이라고 판단하였습니다.

handlers 폴더에 연관이 있는 폴더들에 따라 핸들러 작성 후 index.ts파일을 통해 묶어줍니다.

// src/mocks/handlers/index.ts

export const handlers = [
  ...alarmHandlers,
  ...chapterHandlers,
  ...lectureHandlers,
  ...missionGalleryHandlers,
];

src/mocks 파일 안에 browser.ts 파일 안에 아래와 같은 코드를 입력합니다.

// src/mocks/browser.ts
import { setupWorker } from 'msw/browser';

import { handlers } from './handlers';

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

또한, 노드 환경 변수에 따라 MSW를 사용하기 위한 분기를 포함하여 NODE_ENV가 development인 즉 dev 프로젝트에서만 msw가 실행될 수 있는 분기 코드를 넣어 msw의 세팅을 마무리해 주었습니다.

// src/index.tsx
function prepareMsw() {
  if (NODE_ENV === 'development') {
    return worker.start();
  }

  return Promise.resolve();
}

연결이 되었을 때 확인

성공적으로 MSW가 연결이 되었을 경우에 local의 console에서 위 처럼 mocking을 사용할 수 있다는 문구가 뜨게 됩니다.

Mock Api 만들기

// src/mocks/handlers/alarmHandlers.ts

const getAlarmListHandler = http.get('/alarm-list', () =>
  HttpResponse.json(alarmList, {
    status: 200,
    headers: {
      'Content-Type': 'application/json',
    },
  })
);

간단한 get 요청을 만들어보았습니다.
/alarm-list라는 요청이 온다면 Service Worker에서 요청을 가로채 위에서 작성한 요청을 반환하게 될 것입니다.

// src/mocks/handlers/alarmHandlers.ts

const postAlarmHandler = http.post('/alarm-list/:id', ({ params }) => {
  const { id } = params;

  alarmList.content = alarmList.content.map((alarm) => {
    if (alarm.id === Number(id)) {
      return { ...alarm, isRead: true };
    }

    return alarm;
  });

  return HttpResponse.json(alarmList, {
    status: 201,
    headers: { 'Content-Type': 'application/json' },
  });
});

알림을 읽는 post 요청을 만들어보았습니다.
위와 같은 경우로 /alarm-list/:id 요청이 왔을 때 위 작성된 것을 반환합니다.

Mock Api 활용 테스트 하기

알람 리스트에서 하나의 알람을 읽을 때, post 요청이 가고 이후 get 요청을 다시 요청하여 받아오는 것을 console을 통해 확인 할 수 있었습니다.

적용하며 느꼈던 점 (후기)

api 개발이 진행되며 모킹 서비스를 직접 사용해보니, 프론트 작업 시간이 전보다 매우 여유가 있어질 뿐더러 api의 수정 사항 및 다양한 피드백, 수정사항 등을 반영할 시간이 늘어났다는 점에서 매우 큰 이점이 있다고 생각이 들었습니다.

또한, 다양한 에러를 의도적으로 생성하며 해당 에러에 대한 바운더리 처리 등이 가능하다는 것 또한 매우 큰 이점이라고 생각했습니다.

나아가서는 storybook과 함께 사용하여 api 요청이 들어있는 storybook 설정이 가능하다는 점도 새롭게 느껴졌습니다.

profile
안녕하세요, Frontend 개발자 윤해진입니다.

0개의 댓글