본문 바로가기

FE Article

MSW 에 대해서 아시나요?

안녕하세요 35기 YB 곽지욱입니다 👳‍♀️ 최근에 데이터를 실제로 fetching 하기 전 퍼블리싱 혹은 Mocking 단계에서는 컴포넌트를 어떻게 설계해야할까? 에 대한 고민을 하다가 아이들나라 서정명 님을 만나서 얘기해볼 수 있는 기회가 있었고, 그때 얻은 인사이트를 웨비분들과 공유하고자 합니다!

 

우선 가장 이상적인 프론트와 백엔드의 작업방식은 API 명세가 모두 나온 이후에 FE 개발자가 작업에 들어가는 것입니다. 하지만 현실적으로 그러기 어려운 상황에서는 MSW(Mock Service Worker)를 활용한 API모킹 전략을 이용할 수 있는데요

 

왜냐하면 API 모킹을 통해 실제 백엔드 서비스 없이도 프론트엔드 애플리케이션의 동작을 시뮬레이션 할 수 있기 때문입니다.


MSW 소개

MSW란 리액트 환경에서의 MSW는 브라우저와 Node.js 환경에서 네트워크 요청을 가로채고 모킹할 수 있는 라이브러리입니다.

 

정확히는 MSW를 사용하여 실제 네트워크 요청을 가로채고, 개발자가 정의한 응답으로 대체할 수 있는 것인데요 이를 이용하면 실제 백엔드 서버 없이도 API 요청과 응답을 시뮬레이션 할 수 있겠죠?

 

그리고 요청 지연 이나 상태 코드 등을 설정할 수 있어서 실제 네트워크 요청과 유사한 환경에서 시뮬레이션을 할 수 있습니다.


MSW 작동 방식

MSW가 브라우저에서 동작하는 방식은 다음과 같습니다. 우선 MSW 라이브러리를 설치하면 브라우저에 Servie Worker 를 등록합니다.

 

이후에 브라우저에서 이루어지는 실제 네트워크 요청 들을 (fetch 로 보낸 네트워크 요청 등등) Service Worker 가 가로채게 됩니다.

 

그리고 이 가로챈 요청을 복사해서 실제 서버가 아니라 클라이언트 사이드에 있는 MSW 라이브러리로 보낸 후에 등록된 핸들러를 통해서 모의 응답을 제공받습니다. 그리고 제공받은 모의응답을 브라우저에게 그대로 전달하게 되는 것입니다.

 

그래서 Service Worker가 뭔데?

서비스 워커는 브라우저가 백그라운드에서 실행하는 스크립트를 말하고, 웹 서비스와 브라우저 및 네트워크 사이에서 프록시 서버 의 역할을 합니다.


사용 방법

  1. 설치
npm install msw --save-dev
  1. 핸들러 정의
// src/mocks/handlers.js
import { rest } from 'msw'; //rest 객체 가져오기 API ㅇ청을 모킹하기 위한 헬퍼 제공

export const handlers = [
  rest.get('/api/user', (req, res, ctx) => { //res 응답 , ctx 응답내용 설정
    return res(
      ctx.status(200),
      ctx.json({ id: 1, name: 'John Doe' })
    );
  }),
];
  1. Service Worker 설정
// src/mocks/browser.js
import { setupWorker } from 'msw';
import { handlers } from './handlers';

export const worker = setupWorker(...handlers); //인스턴스 생성 및 요청 핸들러 정의
  1. Worker 실행

어플리케이션이 실행 될 때 워커를 실행하는 코드를 추가

// src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

if (process.env.NODE_ENV === 'development') {
  const { worker } = require('./mocks/browser')
  worker.start()
}

ReactDOM.render(<App />, document.getElementById('root'))
  1. 적용 확인
[MSW] Mocking enabled.

 

어플리케이션을 다시 시작하고, 브라우저 콘솔에서 아래와 같은 메세지가 뜨면 모킹이 활성화 된 것이다.

그리고 이제 클라이언트에서 요청을 보내게 되면

fetch('/api/user')
  .then((response) => response.json())
  .then((data) => console.log(data)); // { id: 1, name: "John Doe" }
{ id: 1, name: "John Doe" }

 

이렇게 정상적으로 데이터를 받아볼 수 있습니다

마무리

현재 진행 중인 프로젝트에 MSW를 도입해 개발을 하니깐 굉장히 편리하다고 느꼈기 때문에 공유하고 싶었습니다. 정해진 기간에 백엔드와 프론트엔드가 동시에 개발을 시작하는데 API가 준비되지 않은 상황에서 프론트 개발을 빠르게 할 수 있다는 점이 너무 크게 다가왔었고,

 

백엔드 작업 속도에 의존도를 많이 줄이고 독립적으로 작업할 수 있어서 오히려 테스트 시간을 더 많이 확보한다거나 리팩토링 기간을 더 길게 잡는다던가 하는 일정 조율이 가능해서 추천드립니다.

 

그리고 특히 직접 네트워크 응답 상태 를 조절하면서 내가 원하는 화면 (성공 화면, 로딩 화면, 에러 화면) 을 효율적으로 개발할수 있었고 req 에 에러코드를 전달해서 디버깅도 가능합니다.

 

참고 및 사진 출처