개발

프론트엔드 치트키[1] - MSW(Mock Service Worker)

dohye1 2022. 10. 19. 10:40
반응형

사실 어그로를 끌려고 제목을 저렇게 적어봤다ㅎ

 

근데 난 치트키라고 생각하긴함.

왜냐면 프론트작업에서 귀찮은 작업을 줄여주기때문임!

MSW

  • DX를 위한 Mock Service Worker
  • 웹 프론트 개발자가 API구현 작업의 영향을 덜 받게 하여 DX를 개선하는것이 목표
  • 브라우저에 몰래?숨어있다가 마치 백앤드 API인 척하면서 프론트엔드의 요청이 발생하면 Mock 데이터를 응답해줌

https://yozm.wishket.com/magazine/detail/1711/

위 그림이 프론트엔드 작업 플로우를 잘 표현한다고 생각해서 첨부해봄

 

새로운 기능이나 페이지를 만들때, api가 아직 준비가 안되어 있는 경우가 많다.

그럴때마다 우리 팀은 mock파일을 만들어 가짜 데이터를 만들었다.

 

그리고 비동기에 대한 처리(로딩 표현, state에 값 넣어주기 등)도 나중에 api를 연결할때 처리를 해주는경우도 있었기때문에

2번이나 작업(퍼블리싱 할 때 /api연동 할 때)하는일이 많았다.

(근데 이건 퍼블리싱할때 비동기 처리를 해줘도되긴한데, 내가 귀찮아서 안한거임. 점심메뉴는 그렇게 신중하게 고르면서 코드는 대충짜네ㅠㅜㅠ)

 

API 개발 작업에 대한 의존성을 낮추자!

  • 프론트 개발 시 API 개발 작업에 대한 의존성을 낮추려면 결국 API가 필요한 시점에 실제로 존재하는 것처럼 가장해야하고, 이를 Mocking이라고 한다.
  • MSW는 브라우저의 Service Worker에서 동작한다.
  • 서비스 워커(Service Worker)를 사용하면 브라우저로 부터 나가는 요청이나 들어오는 응답을 중간에서 감시하거나 변조, 캐싱과 같은 기존에 웹에서 할 수 없었던 부가적인 작업들을 할 수 있다.

 

Mock data 의 위치에 따른 특성을 생각해보자

1. Mock데이터가 어플리케이션 로직 내부에 섞여있는 경우

  • 비지니스 로직 내에서 mocking을 하면 쉽게 moking할 수 있는 반면, 실제 API 연동 코드로 교체해주는 작업을 추가로 해야한다.

2. Mocking용 서버를 외부에 만드는 경우

  • 외부 mocking용 api server를 만들어야한다.
  • 이럴거면 실제 api를 빨리 만드는게 나을지도..?

3. Mocking을 서비스 워커에서 하는 경우 - MSW 

  • 웹 어플리케이션의 비지니스로직에 Mocking코드가 들어가지않는다.
  • api endpoint를 실제 api의 것으로 사용할 수 있다.
  • js를 이용해 웹 어플리케이션 프로젝트에 Mocking코드를 작성하는것이라, 프론트엔드 개발자가 쉽게 이용할 수 있다.
  • 실제 api 개발이 완료되면, MSW에서 핸들러만 제거하면 교체가 끝난다.

 

실습

- react-query와 msw를 같이 사용해봤다.

msw를 사용하면 퍼블리싱과 api연동을 분리해서 작업할 필요가없을것같아 한번에 처리가 가능한 방식으로 생각해봤다.

 

일단 

react프로젝트에 실습을 해봄

(이 글을 보고 따라했습니다.)

 

1. msw를 설치해준다.

npm install msw -d

2. 그리고 service worker를 사용할 수 있는 환경을 세팅해준다.

npx msw init public/ --save

위 명령을 실행하면 public 폴더에 mockServiceWorker.js라는 파일이 생성된다. 근데 코드는 잘 이해가 안가긴함..ㅜㅠ

족흠 어렵네

3. mock api 적어주기

src밑에 mocks라는 폴더를 만들어주고

그 안에 handler.js라는 파일을 만들어줬다.

import { rest } from "msw";

const todos = ["React", "Svelte", "Vue", "Node"];

export const handlers = [
  // 할일 목록
  rest.get("/todos", (req, res, ctx) => {
    return res(
      ctx.status(200),
      ctx.json({ data: todos }),
    );
  }),

  // 할일 추가
  rest.post("/todos", (req, res, ctx) => {
    todos.push(req.body);
    return res(ctx.status(201));
  }),
];

4. worker에 추가해주기

mocks폴더에 worker.js를 만들어주고 아래의 내용을 적는다.

import { setupWorker } from "msw";
import { handlers } from "./handler";

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

워커에 내가 작성한 api를 연결해주는 코드같다.

setupWorker에 handlers를 넘겨줄때 spread 문법을 쓰지않으면 에러가난다!

꼭 붙이기!

5. worker 실행시키기

index.js에 아래의 코드를 추가해준다.

...
import { worker } from "./mocks/worker";
if (process.env.NODE_ENV === "development") {
  worker.start();
}
...

개발 모드일때만 워커가 실행되도록 한다. (이건 개발자마음대로 조건 정하면될듯)

 

 

세팅은 끝났으니 이제 사용해보자!

 

나는 react-query를 사용할거라 react-query도 설치해 줬다.

 

나는 app.js에 간단하게 테스트를 해봄

async function fetchTodo() {
  return await fetch("/todos").then((response) => response.json());
}

function App() {
  const { data, isLoading } = useQuery("todos", fetchTodo);

  console.log(data);

  if (isLoading) {
    return <div>Loading..</div>;
  }

  return (
    <div className="App">
    	Hello world~
    </div>
  );
}

hander.js에 /todos를 작성해줬었는데, 실제로 사용할때 저렇게 path만 적어주면 된다!

 

 

앞으로 잘 써봐야겠군

혹시 잘못된내용이있다면 댓글에 남겨주십쇼소솟...