MSW로 백엔드 의존성 줄이기

date
Nov 8, 2023
slug
mockup-service-worker
author
status
Public
tags
Etc
summary
type
Post
thumbnail
3D Renders Paris Bilal.jpg
category
updatedAt
Nov 11, 2024 01:57 PM

Mock Service Worker

Mock Service Worker (MSW)네트워크 레벨에서 HTTP 요청을 가로채서 Mock을 만들어 주는 라이브러리입니다. 이 라이브러리는 네트워크 라이브러리 (axios, react-query 등)와 함께 사용할 수 있으며, 개발 환경에서 테스트와 디버깅에 용이합니다.
MSW는 브라우저에서 다음과 같이 동작합니다. 먼저, MSW 라이브러리를 설치하면 브라우저에 Service Worker을 등록합니다. 그런 다음, 실제 네트워크 요청 (예: fetch 이벤트로 보낸 네트워크 요청)이 Service Worker에 의해 가로채집니다.
Service Worker는 가로챈 요청을 복사해서 실제 서버 대신 클라이언트 사이드에 있는 MSW 라이브러리에 보내고, 등록된 핸들러를 통해 모의 응답(Mocked response)을 제공받습니다.
마지막으로, 제공받은 모의 응답(Mocked response)을 브라우저에게 그대로 전달합니다. 이 과정을 통해 실제 서버와 직접적인 연결 없이 보내는 요청에 대한 응답을 모의(Mock)할 수 있습니다. 따라서 백엔드 API가 아직 준비되지 않은 경우에도 MSW로 가상 API를 등록하고 프론트에서 테스트할 수 있습니다.
 
Nuxt.js에 MSW 환경 설정하기
yarn add -D msw
*msw 1.3.2 버전을 사용하였습니다.
MSW는 브라우저에서 서비스 워커를 통해서 작동하기 때문에 서비스 워커 등록을 위한 기본적인 코드가 필요한데요. 다행히도 서비스 워커에 대해서 잘 몰라도 MSW에서 제공하는 CLI 도구를 사용하면 이 코드를 쉽게 만들어 낼 수 있습니다.
npx msw init public/ --save
 
notion image
 
*mockData에는 json으로된 mockup들을 넣어주세요.
다음으로 msw 모듈에서 제공하는 setupWorker() 함수를 사용해서 서비스 워커를 생성하겠습니다. 위에서 작성한 요청 핸들러 코드를 불러와서 그대로 setupWorker() 함수의 인자로 넘겨주면 됩니다.
//browser.js import { setupWorker } from 'msw'; import { handlers } from './handlers'; export const worker = setupWorker(...handlers);
//server.js import { setupServer } from 'msw/node'; import { handlers } from './handlers'; export const server = setupServer(...handlers);
 
마지막에 nuxt config.js에 plugin으로 등록하기
//nuxt.config.js plugins: [{ src: '~/plugins/common/Mocks', mode: 'client' }],
 
가짜 API를 구현하려면 요청이 들어왔을 때 임의의 응답을 해주는 핸들러(handler) 코드를 작성해야합니다.
REST API를 모킹할 때는 msw 모듈의 rest 객체를 사용합니다.
GET 요청 예시 코드
//hanlder.js import { rest } from 'msw'; import faqData from './mockData/faqData.json'; export const handlers = [ // 고객 지원 FAQ 조회 API rest.get('https://baseUrl/faqs', (req, res, ctx) => { const page = req.url.searchParams.get('page'); const rows = req.url.searchParams.get('rows'); const startIndex = (page - 1) * rows; const endIndex = startIndex + parseInt(rows, 10); const paginatedContents = faqData.slice(startIndex, endIndex); const totalPages = Math.round(faqData.length / 10); const simulateError = false; if (simulateError) { return res( ctx.status(500), ctx.json({ result: { success: false, code: '1000', message: 'An error occurred while processing the request.' } }) ); } return res( ctx.status(200), ctx.json({ result: { success: true, code: '0000', message: '' }, data: { contents: paginatedContents, totalPages: totalPages, totalRows: faqData.length, page: Number(page) } }) ); }), ];
 

Service Worker란?

Service Worker는 웹 서비스와 브라우저 및 네트워크 사이에서 프록시 서버의 역할을 하며, 오프라인에서도 서비스를 사용할 수 있도록 합니다. Service Worker의 수명 주기는 웹 페이지와는 완전히 별개이기 때문에 다양한 기능에서 사용됩니다. 여러 가지 목적으로 사용될 수 있으며, 네트워크 요청을 가로채서 네트워크 사용 가능 여부에 따라 적절한 행동을 취하며, 서버의 자산을 업데이트할 수 있습니다. 또한 푸시 알림과 백그라운드 동기화 API로의 접근도 제공합니다.
 
[용도]
  • 높은 비용의 계산을 처리할 때, 푸시 이벤트를 생성할 때
  • 백그라운드 데이터 동기화
  • 다른 출처에서의 리소스 요청을 응답
  • 위치정보, 자이로 센서 등 계산에 높은 비용이 들어가는 다수의 페이지에서 함께 사용할 수 있도록 데이터 업데이트를 중앙화
  • 개발 목적으로서 CoffeeScript, Less, CJS/AMD 모듈 등의 의존성 관리와 컴파일 백그라운드 서비스 훅
  • 특정 URL 패턴에 기반한 사용자 지정 템플릿 제공
  • 성능 향상, 필요로 할 것으로 생각되는 리소스의 pre-fetching 등
 
사용 요건
HTTPS 보안 프로토콜 환경이 필요합니다. (localhost 환경 제외) 네트워크 중간에서 연결을 가로채고 조작하는 기능 때문에 반드시 HTTPS가 제공되어야 합니다.