Jelly Diary

[🐾JellyDiary] React 에서 MSW(MockServiceWorker) 이용하여 API 백엔드 Mocking 하기

밍띠이 2024. 4. 25. 20:02
반응형

 

이번 프로젝트를 진행하던 중 백엔드 개발 일정에 차질이 생겨 백엔드 서버가 구현되기 전에 프론트단 개발을 진행하는데에 어려움이 있어 목업 데이터를 생성해서 테스트 해보며 개발을 진행하고자 MSW 를 이번 프로젝트에 도입하게 되었다.

 

프로젝트는 React + Typescript + Vite 구성으로 진행 되었다.


1. MSW(Mock Service Worker) 란?

https://mswjs.io/docs/getting-started

 

Getting started

Three steps to get started with Mock Service Worker.

mswjs.io

 

MSW란 서비스워커를 사용하여 네트워크 요청을 가로채서 관찰하고 모의 응답을 사용할 수 있는 라이브러리이다.

프론트엔드에서 마냥 백엔드 API 개발만을 기다릴 수 없기 때문에 미리 결과 값을 만들어 놓고 호출하여 테스트 해볼 수 있는 

자바스크립트 라이브러리라고 생각하면 된다.

 

이번 프로젝트에서 특히 유저 권한에 따라 보여줘야 하는 데이터 들이 달라지는 경우가 많기 때문에 사전에 적용해 보는 기간이 꼭 필요했다.

 

사용방법은 라이브러리 문서에 잘 나와있어 정리해보고자 한다.


2.  라이브러리 설치

npm install msw@latest --save-dev

 

3. 요청 핸들러 작성(Request handlers)

// src/mocks/handlers.ts
import { http, HttpResponse } from 'msw'
 
export const handlers = [
  http.get('/user', () => {
    return HttpResponse.json({
      id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d',
      firstName: 'John',
      lastName: 'Maverick',
    })
  }),
]

handlers 파일을 생성하여 mock get API 를 작성해 줄 수있다. /user 엔드포인트로 가는 요청을 가로채 json 형식으로 반환해 줄 수 있다. 

값이 많아지면 핸들러와, 리턴 값을 따로 파일로 관리할 수도 있다.

4. 요청 핸들러 관리

import userHandler from './userHandler';
import diaryHandler from './diaryHandler';

export const handlers = [...userHandler, ...diaryHandler];

핸들러가 많아지는 경우 관리가 어려워 핸들러만 따로 관리하는 파일을 하나 만들어 주었다.

 

5. 브라우저 MSW 셋팅(browser)

// src/mocks/browser.ts
import { setupWorker } from 'msw/browser'
import { handlers } from './handlers.ts'
 
export const worker = setupWorker(...handlers)

리액트 웹 어플리케이션에 적용하려면 setupWorker을 사용하여 브라우저 셋팅을 해 주어야 한다.

6. 개발 환경에서만 msw 를 사용하도록 설정(Conditionally enable mocking)

// src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { App } from './App'
 
async function enableMocking() {
  if (process.env.NODE_ENV !== 'development') {
    return
  }
 
  const { worker } = await import('./mocks/browser')
 
  return worker.start()
}
 
enableMocking().then(() => {
  ReactDOM.render(<App />, rootElement)
})

 

.env 의 환경 변수를 통해 개발환경에서만 목업 데이터로 보여주게 설정할 수 있다.

7. 확인

[MSW] Mocking enabled.

콘솔에서 'Mocking enabled' 를 확인할 수 있으면 설정이 완료 된 것이다.

 

8. REST API + MSW

GET, POST, DELETE 를 가진 기본 RESTful API 요청

// src/mocks/handlers.ts
import { http } from 'msw'
 
export const handlers = [
  http.get('/posts', () => {
    console.log('Captured a "GET /posts" request')
  }),
   http.post('/posts', () => {
    console.log('Captured a "POST /posts" request')
  }),
  http.delete('/posts/:id', ({ params }) => {
    console.log(`Captured a "DELETE /posts/${params.id}" request`)
  }),
]

 

구조화 된 json 파일이 있다면 아래와 같이 불러오거나 인수를 받아 처리할 수 있다.

import { http, HttpResponse } from 'msw'
 
const allPosts = new Map()
 
export const handlers = [
  http.get('/posts', () => { // HttpResponse를 통해 enable 결과 반환
    return HttpResponse.json(Array.from(allPosts.values()))
  }),
 http.post('/posts', async ({ request }) => { // 'request'인수를 사용하여 요청
    const newPost = await request.json()
 
    allPosts.set(newPost.id, newPost)
 
    return HttpResponse.json(newPost, { status: 201 })
  }),
  http.delete('/posts/:id', ({ params }) => { // 'params'를 사용하여 경로 처리
    const { id } = params
 
    const deletedPost = allPosts.get(id)
 
    if (!deletedPost) {
      return new HttpResponse(null, { status: 404 })
    }
    
    allPosts.delete(id)
 
    return HttpResponse.json(deletedPost)
  }),
]

 

쿠키를 받아 처리할 수도 있다.

http.get('/user', ({ cookies }) => {
  const { session } = cookies
 
  if (!session) {
    return new HttpResponse(null, { status: 401 })
  }
})

 

 


 

간단하게 json 파일을 작성하여 목킹을 할 수 있어서 굉장히 편리했다.

실제 서버단과 연결 하는 것과 차이는 있겠지만 충분히 미리 작업해 볼 수 있어서

개발에 도움이 되었다.

반응형