이번 TOJ 프로젝트를 진행하면서 협업을 하는 과정 중에 가장
고려를 많이 했던 부분이 있었다.
프로젝트 초기에 , 프론트엔드는 어떻게 개발을 진행해 나가야 할까?
논리대로라면 , 프론트엔드는 백엔드에서 작성한 API가 완성이 된 이후에
개발을 진행할 수 있다.
프론트엔드는 API를 기반으로 화면 로직을 그려 나가야 하며
개발 과정에서 도출되는 요구 사항이나 사용 가능한 인터페이스에 변경이 있으면
각 단계별 의존성에 따라 다시 작업해야 하는 경우가 발생하기 때문에
개발과정이 다음과 같이만 진행된다면 요구 사항과 제공된 스펙에 따라
순조롭게 프론트엔드 개발을 진행할 수 있기 때문이다.
출처 : https://tech.kakao.com/2021/09/29/mocking-fe/
그렇지만 실제로 그 어떠한 곳에서도 위와 같은 방식으로 개발을 진행하지 않는다.
우리에겐 시간과 자원이 무한정으로 주어지 않기 때문이다.
그러므로 현실에서는 프론트엔드와 백엔드가 동시에 개발을 진행하게 된다.
출처 : https://tech.kakao.com/2021/09/29/mocking-fe/
그렇지만 이런 방식으로 진행을 하다 보면 당연히 프론트엔드에서 백엔드 API에 종속적인 부분이 있을 때,
해당 API가 완성되기 전까지는 프론트엔드에서 개발을 진행할 수 없는 현상이 발생하게 되고 ,
예상한 기간보다 API 개발에 시간이 더 필요해진 경우, 그 시간만큼 프론트엔드 개발자가
개발을 진행하지 못하는 상황이 발생하게 된다.
그래서 Kakao Tech 에서 제공하는 목표는 백엔드 개발과 최대한 병행해 개발을 진행하면서
최대한 프론트엔드의 대기 시간을 줄이는 것이다.
출처 : https://tech.kakao.com/2021/09/29/mocking-fe/
그리고 이를 위한 해결책은 바로 MSW를 통해 Mocking을 보다 제대로
활용하는 것이었다.
요구사항 도출
프론트엔드에서 백엔드에 종속적인 개발 영역이 있는 경우
(=API) 필요한 API의 스펙을 사전 협의하여 백엔드 개발자에게 받는다
💡 이때 API 스펙을 구성하는 주체는 백엔드 혼자 하거나, 프론트엔드와 같이해도 무관하다.사전에 전달받은 스펙을 기반으로 프론트엔드 에서는 Mocking 데이터를 생성하고,
이를 기반으로 개발을 진행한다
여기서 , Kakao Tech 블로그를 보면 아래와 같은 문구가 적혀 있다
때로는 API 자체에 대한 의존성을 일단 가져가지 않고,
Mocking을 통해 개발을 진행한 다음, 실제 사용해야 하는 API가
나온 시점에서 API의 실제 인터페이스에 맞게 컨버팅하는 과정을 따로 가지는 개발 방법으로 진행하기도 합니다.
즉 , 프론트엔드가 API 스펙을 사전에 전달 받지 않고
우선 프론트엔드 자체적으로 API 스펙을 임의로 구성해서
Mocking을
진행한 다음 실제 API가 완성되면 이에 맞춰서 스펙을 변경하는 것이다
너무 자세한 명세까지는 같이 작성하는게 아니고, 페이지마다 필요한 API 정도만 사전에 협의를 하고
프론트엔드 자체적으로 Mocking을 통해 개발을 진행한 다음
추후 프론트는 백엔드가 공유해준 명세에 맞춰서 수정하는 것이다
사전에 협의된 API 명세는 개발중에 변경이 될 가능성이 높다
이는 개발을 진행하면서 당연한 부분이고 더군다나 우리 프로젝트는 따로 기획자가 있는 것도 아니므로
중간중간 요구 사항이나 방향성 역시 수정이 될 수 있다.
그래서 구현해야 할 화면에서 꼭 전달받아야 하는 데이터만 추상적으로 협의하고 개발을 하는
것이 오히려 더 개발 생산성 측면에서 효율적이라는 판단이 들었기 때문이다.
화면에 필요한 데이터의 상태를 애플리케이션의 내부 로직에 직접 Mocking 해서 필요한 화면에 붙이는 방식
네이티브 모듈 (http, https, XMLHttpRequest)을 바꿔치기해서 원하는 응답을 받을 수 있게 Mocking 하기
Mocking 서버 만들기
MSW는 Service Worker를 이용해 서버를 향한 실제 네트워크 요청을 가로채서 모의 응답 (Mocked response)를 보내주는 API Mocking 라이브러리이다.
MSW를 사용하면 직접 Mock 서버를 구현하지 않아도,
네트워크 수준에서 API를 Mocking 할 수 있다.
MSW가 이런 기능을 제공할 수 있는 이유는 바로 Service Worker를 이용해 HTTP 요청을 가로채기 때문이다.
Service Worker는 브라우저가 백그라운드에서 실행하는 스크립트로, 애플리케이션의 UI 블록 없이 연산을 처리할 수 있다.
즉, 브라우저로 부터 나가는 요청이나 들어오는 응답을 중간에서 감시하거나 변조, 캐싱과 같은 기존에 웹에서 할 수 없었던 부가적인 작업들을 할 수 있는 것이다
(웹 애플리케이션의 메인 스레드와 분리된 별도의 백그라운드 스레드에서 실행)
Service Worker는 웹 서비스와 브라우저 및 네트워크 사이에서 프록시 서버의 역할을 하며, 오프라인에서도 서비스를 사용할 수 있도록 한다.
이러한 특징으로 인해, Service Worker는 다음과 같은 기능에 많이 사용되고 있다
네트워크가 원활할 때 동기화를 시켜주는 백그라운드 동기화 기능
높은 비용의 계산을 처리할 때 또는 푸시 이벤트 생성
MSW의 동작 방식과 관계되어 있는, 네트워크 요청을 가로채는 행위
Service Worker가 애플리케이션과 서버 사이에서 Request를 가로채서 직접 Fetch에 대한 컨트롤도
할 수 있기 때문에 색다른 작업이 가능하다
예를 들어, HTTP Request와 Response를 보고 캐싱 처리를 한다든지, 필요하다면 로깅을 한다든지 하는 여러 가지 새로운 동작을 만들어 낼 수도 있는 것이다.
MSW도 이 과정을 통해서 Request를 가로채서 Response를 Mocking 하는 원리를 사용하는 것이다.
즉, MSW는 Service Worker를 기반으로 모의 API를 만들어내기 때문에
다른 프론트엔드에서 사용하는 수많은 라이브러리나 프레임워크에
종속적이지 않고 호환성에 문제없이 동작한다.
다만 ,Service Worker는 IE와 같은 일부 브라우저에서 지원이 되지 않으며,
네트워크 중간에서 연결을 가로채고 조작하는 강력한 기능 때문에 반드시 HTTPS 보안 프로토콜 환경이
제공되어야 한다.
(localhost 환경에서는 상관 없이 사용이 가능하다)
MSW 라이브러리를 설치하면 브라우저에 Service Worker을 등록
브라우저에서 이루어지는 네트워크 요청들(=API 호출)을 Service Worker가 가로채게 된다.
Service Worker는 가로챈 요청을 복사해서 실제 서버가 아닌 클라이언트 사이드에 있는 MSW 라이브러리로 보낸다
MSW는 등록된 핸들러를 통해 모의 응답(Mocked response)을 Service Worker에게 다시 제공 한다.
Service Worker는 제공받은 모의 응답(Mocked response)을 브라우저에게 그대로 전달한다.
이러한 과정을 통해, 실제 서버와 직접적인 연결 없이 보내는 요청에
대한 응답을 Mocking 할 수 있게된다.
따라서, 백엔드 API가 아직 준비되지 않아도 MSW로 가상 API를 등록하고
프론트에서 테스트할 수 있다.