MSW 도대체 너 정체가 뭐야 !

신태일·2024년 10월 17일

지금까지 프로젝트를 진행할 때 항상 프론트는 나 한명이었고, 그에 따라서 진행해야 하는 부분에 대해 고려사항이 많았다. 기본적인 프로젝트 아키텍처를 어떻게 가져가야 할지, 기술스택은 어떤걸 쓸지, 공통 컴포넌트는 어떤걸로 할지, 등등 나 또한 전체적인 맥락을 가져가는 부분에 있어서 늘 레벨업을 꿈꾸다 보니 나의 프로젝트 접근을 달리 해야 해서 정말 내가 잘하고 있는지 ? 혹시나 이러한 접근이 타인이 볼 때 수정해야 부분이 많아 보일지 ?

늘 완성은 잘 되었지만, 사람들끼리 일하는 협업 부분에 있어서 늘 걱정이 앞섰다. 내가 가져가는 툴들이 다른이들이 볼 때 맞지 않는 부분들이 많을 것이고 다른 이들이 가져가는 방식이 훨씬 효과적이라면 내가 그에 따라가는 식의 수정이 있을 것 같기 때문이다.


서론이 길었다.

지금까지의 프로젝트에서 API 관련한 부분은 늘 명세서에 맞게끔 잘 전달이 되서 MSW 도입에 대해서 생각치도 않고 있었지만 내가 앞으로 실무에서 작업을 할 때 프론트팀끼리 정한 템플릿 양식, 공통 컴포넌트 제작 등등 분업화에 따른 빠른 일처리로 모킹된 데이터를 다뤄야 할 일이 생길 것 같아 미리미리 대처하려고 한다!


MSW 동작 방식

본격적으로 MSW를 설정하기 전, MSW가 무엇이고 어떤 방식으로 동작하는지 간략하게만 짚고 넘어가보자

1. MSW는 무엇이고, 하는 주된 일은 무엇인가?

  • MSW는 Mock Service Worker. 여기서 Mock은 ‘모의’, ‘모조’, ‘가짜’ 라는 뜻이다.

    • 이름 안에 Service Worker가 있는 것처럼, Web에서 제공하는 Service Worker API를 사용해서 HTTP 요청을 가로챈다.
      • Service Worker: 웹 애플리케이션의 메인 스레드와 분리된 별도의 백그라운드 스레드에서 실행시킬 수 있는 기술. 이를 통해 애플리케이션의 UI Block 없이 연산 처리를 할 수 있다. Service Worker를 통해 네트워크 요청이나 응답을 가로채 조작할 수 있게 된다.
  • MSW는 실제 API 요청이 발생하면, 이 요청을 가로채서 미리 준비해 뒀던 Mock data로 응답해준다.

  • MSW를 사용하면 Mock Server를 따로 구축하지 않아도 API를 Mocking할 수 있어서 효율성이 증대된다.

2. Mock Service Worker의 request 흐름

  • 아래 그림은 Mock Service Worker의 request가 어떤 식으로 흘러가는지 큰 그림으로 표현한 것이다. 공식문서를 참조했다.

    1. 브라우저에서 요청을 보낸다.

    2. Service Worker는 요청을 받고, 해당 요청을 복제한다. 복제한 요청을 MSW에게 보낸다.

    3. MSW는 요청과 일치하는 목업을 생성한다.

    4. MSW는 모킹한 응답을 Service Worker에게 보낸다.

    5. Service Worker가 모킹된 응답을 브라우저에게 보내고, 브라우저가 최종적으로 이 응답을 받는다.


3. MSW 세팅 과정(nextjs app router13 기준)

참고: https://mswjs.io/docs/integrations/browser

  1. MSW를 설치하고, public 폴더에 mockServiceWorker 파일을 생성한다.

       // install MSW (package.json dependency에 기록하는 습관을 가지자)
       npm install msw --save-dev
       
       // create mockServiceWorker file in public folder
       npx msw init public/ --save```
    
  2. Handler 함수들을 만들어서 API를 모킹한다.

    • REST API 방식, GraphQL API 방식 중에 선택해서 API를 모킹할 수 있다.

    • 현재 적용하려는 프로젝트는 REST API 방식이어서 msw에서 rest를 import 한 후 사용한다.

      // src/mocks/handlers.ts
      import { http, HttpResponse } from 'msw';
      
      export const handlers = [
        http.post('/api/login', () => {
          console.log('로그인');
          return HttpResponse.json(User[1], {
            headers: {
              'Set-Cookie': 'connect.sid=msw-cookie;HttpOnly;Path=/',
            },
          });
        }),
        http.post('/api/logout', () => {
          console.log('로그아웃');
          return new HttpResponse(null, {
            headers: {
              'Set-Cookie': 'connect.sid=;HttpOnly;Path=/;Max-Age=0',
            },
          });
        }),
       ];

  3. 현재 app 라우터 구동방식으로는 MSW 도입에 에러가 많아서 별도의 node 서버를 만들어서 작동시킨다.

        // src/mocks/http.ts
        
        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}`));
        
  1. 브라우저에도 worker를 설정해준다.
        // src/mocks/browser.ts
        
        import { setupWorker } from 'msw/browser';
        import { handlers } from './handlers';
        
        const worker = setupWorker(...handlers);
        
        export default worker;
        
profile
노원거인

0개의 댓글