MSW 잘 사용하기: 유저가 보는 부분에 따라 데이터 쪼개기

Youngjin
Dong-gle
Published in
7 min readOct 18, 2023

이 글은 동글을 개발하면서 MSW를 어떻게 하면 잘 활용할 수 있을지 고민하고 적용한 과정에 대한 글입니다.

또한 프론트엔드 개발에서 쓰이는 MSW에 대한 기본적인 이해가 있어야합니다.

MSW를 이용해 개발을 해보신 경험이 있다면 더욱 좋습니다.

1. 데이터 모킹의 필요성

프로젝트를 만들면서 어떤 기능를 완성하기 까지는

기획 -> API 논의 -> 백엔드 개발 -> 프론트엔드 개발 -> 배포 의 단계를 거친다.

프론트는 데이터를 받아와서 유저가 보는 부분을 개발하기 때문에, 백엔드에 의존적일 수 밖에 없다.

하지만 공수기간을 맞추려면 마냥 백엔드 기능이 완성되기 까지 기다릴 수는 없다.

이때 API 문서를 보고 데이터를 모킹해서 개발할 수 있다.

2. MSW을 이용하며 마주한 문제

MSW를 이용하면 요청을 쉽게 가로채서 내가(프론트엔드 개발자) 원하는 응답을 만들어서 보낼 수 있다.

API 문서에 명시된 데이터 형식에 따라 목 데이터를 만들어서 보내주면 된다.

데이터가 담긴 하나의 db.ts를 만들었고, 그 데이터를 이리저리 조작하며 모킹했다.

하지만 프로젝트의 규모가 커지고 기능이 복잡해지면서, 모킹 로직이 복잡해지기 시작했다.

POST, DELETE, PATCH 뿐 아니라 GET 마저도 응답을 보내기 전 가공작업이 필요했다.

기능 구현보다 모킹 로직 구현하는데 시간을 더 쓰는 경우(…)도 있었다.

그 때 심정은 내가 날린 한 PR에 고스란히 담겨있다.

그래서 많은 고민을 거친 후, MSW를 이용하는 방식을 갈아엎기로 결정했다.

3. MSW 로직 정비하기

동글의 MSW 로직은 정말 복잡했다.

체계가 없었기 때문에 개발자마다 다른 방식으로 모킹했다.

그래서 이런 문제점들이 보였다.

  • 핸들러마다 사용하는 목 데이터의 원천이 다르다
  • 한 핸들러에 성공과 실패여부가 같이 있거나 하나만 있다.
  • POST, DELETE, PATCH 요청이지만 데이터 조작이 복잡해서 그냥 200을 날린다.

MSW 로직을 정비하기전에 나는 한가지 규칙을 정했다.

성공(200, 201, 204) 하는 경우만 모킹, 에러 상황은 모킹하지 않음

에러가 나는 경우는 일단 배제했다.

다 고려하려면 로직이 복잡해져서 모킹 로직을 작성하기에 까다롭다.

요청 성공 시 유저에게 보이는 부분에 대해 집중하는게 더 중요하다고 생각한다.

에러 상황에 대한 렌더링은 나중에 cypress 테스트로 검증하면 된다.

3.1 프로젝트 API 파악하기

모킹 로직을 정비하기 위해 동글에서 쓰고있는 API를 파악할 필요가 있었다.

API가 늘어나면서, 어떤 기능이 있는지 한번에 파악하기 힘든 참이었다.

그래서 동글의 모든 기능과 API로직을 시각화했다.

3.2 목 데이터의 원천 나누기

MSW를 이용하면서 내가 꼽은 문제점은 프로젝트가 커지면서 모킹로직이 너무 복잡해진다는 것이었다.

위에서 “데이터가 담긴 하나의 db.ts를 만들었고, 그 데이터를 이리저리 조작하며 모킹했다.” 라고 말했듯이, 백엔드의 로직을 그대로 따라하려 했던 게 화근이었다.

그래서 GET요청 마다 목 데이터를 선언하기로 결정했다. (위 시각화 그래프에서 노란색 박스)

즉 하나였던 원천을 보이는 부분에 따라 여러개로 쪼개는 작업이다.

이렇게 하면 GET 응답 데이터는 가공할 필요가 없어진다.

POST, DELETE, PATCH 핸들러에서는 변화를 줘야하는 데이터들을 조작하면 된다.

그러면 프론트에서 GET을 요청했을때 변화된 데이터를 보내줄 수 있다.

3.3 목 데이터의 원천 나누기: 예시

휴지통 글을 복구하면 두 가지 동작이 잘 일어나는지 확인해야한다.

  • 복구한 글이 테이블에서 사라진다.
  • 복구한 글을 왼쪽 사이드바 카테고리에서 확인할 수 있다.

이 동작을 모킹하기 위해서 조작해야할 데이터는 2개이다.

데이터를 쪼개두었기 때문에 각각 조작할 수 있다.

또한 가공 작업(데이터가 객체라면 필요한 필드만 뽑아서 다른 형식의 응답 데이터를 만드는 작업이라던지..)이 필요없어서 모킹 로직도 간단하다.

저 메서드들은 단순 필터링과 배열 원소 추가정도의 로직만 수행한다.

모킹을 단순하게 구현할 수 있다는 게 포인트다.

4. 모킹에 지나친 디테일은 필요없다

목 데이터를 쪼개면 얻을 수 있는 장점들을 알아보았다.

하지만 여기서도 어느 정도까지 배열(데이터)조작을 디테일하게 구현해야할 지 경계가 모호하다.

나는 그 부분에 대해서는 각자 알잘딱하게 구현하는 게 좋다고 생각했다.

예를 들어 글을 조회할 때, 모든 글이 같은 글을 던져주도록 하는 것이다.

클릭한 글에 맞는 내용을 잘 표시하는지 까지는 중요하지 않다.

그저 글을 클릭했을 때 잘 불러오는지 정도면 충분하다고 생각했기 때문에
그것을 확인할 수 있을정도 까지만 모킹을 구현했다.

확인하고 싶은 “동작”을 챙기자

보이는 부분에 대해 자신감을 가지고 싶은 부분에 대해서는
테스트 배열을 잘 조작하여 핸들러를 구성하면 된다.

예를 들어 나는 글 삭제, 복구를 했을 때 의도대로 (휴지통에 글이 들어가고, 복구 시 왼쪽 사이드바 카테고리 글을 invalidate 하는지) 동작하는지 보고 싶었다.

그래서 그와 관련된 category.ts, trashCanPage.ts 파일에 있는 데이터를 조작했다.
여기서 포인트는 삭제된 글의 제목이 실제 삭제된 것과 다르다는 것이다.
즉, 로직을 너무 구체적으로 작성하지 않아도 되고, 해당 ‘동작’ 을 프론트에서 확인 할 수 있게만 목 데이터를 넣어준다면 충분하다.

5. 생각 정리

MSW 로직을 정비한 후로 개발이 꽤 편리해진걸 체감했다.

하지만 성공하는 로직에 대해서만 핸들러를 만드는 부분은 아쉽다.

핸들러를 실패하는 경우로 override하는 로직을 만들어 두면 어느정도 해결할 수 있을 것 같다.

또 실패하는 경우도 cypress로 테스트하면 좋을 것 같다.

동글은 cypress도 msw 서버를 이용하여 테스트하기로 했기 때문에 모킹을 정비할 때 좀 더 신중하게 접근했다.

현재 모킹 로직을 단순하게 작성할 수 있으면서 또 어느정도 디테일은 챙기는 적정선을 찾은 것 같아 기쁘다.

덕분에 개발속도가 올라간게 체감이 된다.

--

--