<figure class="image image_resized" style="width:100%;"><a href="https://www.wishket.com/crsr/?next=/w/EaN4AhXVQN/&referer_type=7110000705"><img src="https://yozm.wishket.com/media/news/1711/%EC%9C%84%EC%8B%9C%EC%BC%93_%EC%A0%84%ED%99%98_%EB%B0%B0%EB%84%88.png"></a></figure><p style="text-align:justify;"> </p><p style="text-align:justify;">국내 유명 IT 기업은 한국을 넘어 세계를 무대로 할 정도로 뛰어난 기술과 아이디어를 자랑합니다. 이들은 기업 블로그를 통해 이러한 정보를 공개하고 있습니다. 요즘IT는 각 기업의 특색 있고 유익한 콘텐츠를 소개하는 시리즈를 준비했습니다. 이들은 어떻게 사고하고, 어떤 방식으로 일하는 걸까요?</p><p style="text-align:justify;"> </p><p style="text-align:justify;">이번 글은 국내 화장품 시장의 정보 비대칭 문제를 해결하고 소비자 중심의 뷰티 시장을 만들어 가고 있는 ‘화해’의 프론트엔드 개발팀의 이야기입니다. 개발자가 API 구현 작업의 영향을 덜 받게 하여 DX를 개선하는 상황에 대해 소개하고 있습니다.</p><div class="page-break" style="page-break-after:always;"><span style="display:none;"> </span></div><figure class="table"><table><tbody><tr><td>이 글은 백엔드 개발자에게 <strong>Mocking(모의 개체) 할 필요 없이 API 개발을 빨리 해달라</strong>고 눈치를 주려는 게 아닙니다. 웹 프론트엔드 개발자가 API 구현 작업의 영향을 덜 받게 하여 DX(Developer eXperience)를 개선하는 것이 목표입니다.</td></tr></tbody></table></figure><p style="text-align:justify;"> </p><p style="text-align:justify;">웹 프론트엔드 개발을 하면 자연스럽게 서버에서 제공되는 API를 이용해서 정보를 받아오거나 정보를 보내서 응답을 받은 후에 액션을 처리하는 작업을 하게 됩니다. 이와 같은 작업을 진행할 때 이미 API 스펙이 잘 정리되고 구현이 완료된 상황이라면 UI를 구현하면서 바로 API로 받아온 정보를 화면에 표시할 수 있습니다. 또 유저 액션에 대해서 API 요청 후 응답에 대한 리액션도 바로 구현할 수 있을 것입니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"> </p><h3 style="text-align:justify;"><strong>DX를 떨어뜨리는 이슈 발생!</strong></h3><p style="text-align:justify;">이처럼 순탄하게 개발할 수 있으면 제일 좋겠지만, 현실적으로는 그러지 못할 수 있습니다. 제가 속한 밴드에서도 스프린트 단위마다 API 개발과 프론트엔드 개발이 동시에 이루어집니다. 그래서 자연스럽게 스프린트 초기에는 API 스펙이 없는 상태로 프론트엔드 개발을 시작합니다.</p><p style="text-align:justify;"><span style="color:#00a878;">※ 항상 API 구현이 늦는 건 아닙니다. DX가 떨어지는 상황을 설명하기 위해서 API 구현이 늦어지는 상황을 가정합니다.</span></p><p style="text-align:justify;"> </p><p style="text-align:justify;">API 개발이 늦어지는 상황에서는 아래와 같은 흐름으로 프론트엔드 개발자의 DX가 떨어집니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">1) 먼저 UI 구현 작업을 진행합니다. 이때 API로 받는 정보가 표시될 공간은 임의의 데이터로 하드코딩해서 공간을 채워 둡니다. 만약 UI 작업을 완료할 때까지 API 스펙이 나오지 않았다면 API Endpoint를 비워둔 채 API를 호출하는 코드를 작성합니다. 유저 액션에 의한 API 요청이 필요한 경우에는 이벤트 핸들러 함수를 빈 함수로 만들어 둡니다.</p><ul><li style="text-align:justify;"><strong>이때 발생하는 DX 저하 요인</strong><ul><li style="text-align:justify;">하드코딩한 Mock 데이터는 나중에 교체해야 합니다.</li><li style="text-align:justify;">API 호출 준비를 해뒀지만, Endpoint를 몰라서 호출할 수 없으니 작업을 더 이상 진행할 수 없습니다.</li></ul></li></ul><p style="text-align:justify;"> </p><p style="text-align:justify;">2) API 스펙이 나오면 API를 호출하는 코드를 작성할 수 있습니다. 그리고 응답 모델을 보고 하드코딩했던 데이터를 응답 변수로 교체합니다. 물론, 아직 API 구현이 되지 않았다면 실제 데이터를 불러올 수 없으니 작업을 더 진행할 수는 없습니다. 그래서 대안으로 응답 타입에 맞추어 Mock 데이터 객체를 만들고 이를 API 응답값처럼 이용합니다.</p><ul><li style="text-align:justify;"><strong>이때 발생하는 DX 저하 요인</strong><ul><li style="text-align:justify;">하드코딩한 Mock 데이터 객체를 배포 전에 없애야 합니다.</li><li style="text-align:justify;">임의로 API 호출 성공, 실패 상황을 만들기 위한 코드를 작성해야 합니다. 나중에 잘 지워야 합니다. API 호출 실패 상황이 다양할수록 임의로 작성하는 코드는 많아집니다.</li></ul></li></ul><p style="text-align:justify;"> </p><p style="text-align:justify;">3) API 구현이 완료되면 API 호출 코드를 살리고 API 스펙만 보고 작성했던 코드가 버그 없이 잘 동작하는지 확인합니다.</p><ul><li style="text-align:justify;"><strong>이때 발생하는 DX 저하 요인</strong><ul><li style="text-align:justify;">API를 실제로 호출하는 건 이 단계가 처음이라서 네트워크 이슈나 브라우저 이슈를 만나면 예상치 못한 공수가 추가로 들어갑니다. 그런데 이때가 되면 이미 과제를 완료해야 하는 시점에 다다른 경우가 많습니다.</li><li style="text-align:justify;">간혹 Mock 데이터나 로직을 꼼꼼히 지우지 못해서 불필요한 코드가 main 브랜치에 들어가기도 합니다.</li></ul></li></ul><p style="text-align:justify;"> </p><p style="text-align:justify;">⇒ 종합적으로 보면, 작업이 자꾸 멈추고 개발 속도가 붙지 않습니다. 그리고 배포 전에 교체해서 지워야 하는 코드를 만들어야만 하는 여건은 DX가 떨어질 수밖에 없습니다.</p><p style="text-align:justify;"> </p><figure class="image image_resized" style="width:100%;"><img src="https://yozm.wishket.com/media/news/1711/image001.jpg" alt="프론트엔드 dx 개선"><figcaption><출처: 화해팀 블로그></figcaption></figure><p style="text-align:justify;"> </p><p style="text-align:justify;"> </p><h3 style="text-align:justify;"><strong>API 개발 작업에 대한 의존성을 낮추자!</strong></h3><p style="text-align:justify;">프론트엔드 개발을 할 때 API 개발 작업에 대한 의존성을 낮추려면 결국 API가 필요한 시점에 실제로 존재하는 것처럼 가장해야 하고 우리는 이를 ‘Mocking 한다’고 합니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">사실 위의 사례에서 코드 내에 하드코딩으로 Mocking 한 것도 어느 정도는 의존성을 낮춘 것입니다. 하드코딩 한 덕분에 조금이라도 더 작업을 진행했으니까요. 그러나 웹 애플리케이션의 비즈니스 로직에 Mocking 코드를 넣으면 나중에 해당 코드를 제거하고 실제로 API를 연동하는 코드를 넣어주는 작업을 해야 합니다. 게다가 하드코딩으로 넣는 코드는 API로 동작하는 흐름과 다르기 때문에 교체해야 할 코드의 양이 많습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">웹 애플리케이션 코드에 하드코딩을 하고 싶지 않다면 별도의 Mock API Server를 만들어서 이용할 수도 있습니다. 별도 서버이므로 웹 애플리케이션 코드는 실제 API를 연동하는 로직으로 작성하면 됩니다. 실제 API가 구현되었을 때 API endpoint만 바꿔주면 되니 간편합니다. 그러나 별도 웹서버를 만들어줘야 한다는 장벽은 높습니다. 서버 개발에 대한 지식을 바탕으로 웹서버를 만들 수 있어야 하고, 개발할 때 별도 웹서버를 로컬에 실행해야 합니다. 자칫하면 웹 애플리케이션 코드에 Mocking 하는 것보다 공수가 더 크게 듭니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"> </p><h3 style="text-align:justify;"><strong>MSW로 더 행복하게 Mocking 하자!</strong></h3><p style="text-align:justify;">MSW(Mock Service Worker)는 API를 쉽고 깔끔하게 Mocking 할 수 있게 도와주는 라이브러리입니다. 직접 도입해보니 30분 만에 빠르고 가볍게 활용할 수 있었습니다. 적은 시간을 투자했지만, 그 효과는 정말 뛰어납니다. 개발 시간을 효과적으로 줄여주고 DX를 크게 향상해줍니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">이름에서 볼 수 있듯이 MSW는 브라우저의 Service Worker에서 동작합니다. Service Worker는 웹 애플리케이션의 비즈니스 로직과 별개로 브라우저 단에서 별도의 작업을 실행시킬 수 있는 곳입니다. 특히, 웹 애플리케이션에서 서버로 나가는 API 요청을 가로챌 수도 있습니다.</p><p style="text-align:justify;"> </p><figure class="image image_resized" style="width:100%;"><img src="https://yozm.wishket.com/media/news/1711/image003.jpg" alt="msw mocking"><figcaption><출처: 화해팀 블로그></figcaption></figure><p style="text-align:justify;"> </p><p style="text-align:justify;">위에서 언급했듯이 웹 애플리케이션의 비즈니스 로직 내에서 Mocking을 하면(위 그림에서 Mocking 위치(1)) 쉽게 Mocking을 할 수 있는 반면, 비즈니스 로직에 Mocking 코드가 들어가면 실제 API 연동 코드로 교체하는 작업을 추가로 해줘야 합니다. 또 다른 방법인 별도 Mock API Server를 만드는 건(Mocking 위치(3)) 웹 애플리케이션의 비즈니스 로직에 Mocking 코드가 들어가지 않지만, 웹 서버를 만들어야 하는 부담이 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">그러나 MSW를 이용해서 Service Worker에서 Mocking 하는 것(Mocking 위치(2))은 아래와 같은 장점이 있습니다.</p><ul><li style="text-align:justify;">웹 애플리케이션의 비즈니스 로직에 Mocking 코드가 들어가지 않습니다.</li><li style="text-align:justify;">API endpoint를 실제 API의 것으로 사용할 수 있습니다.</li><li style="text-align:justify;">JavaScript를 이용해 웹 애플리케이션 프로젝트에 Mocking 코드를 작성하는 것이라서 프론트엔드 개발자가 쉽게 이용할 수 있습니다. (비즈니스 로직에 MSW 코드가 들어가지는 않습니다.)</li><li style="text-align:justify;">실제 API 개발이 완료되면, MSW에서 핸들러만 제거하면 교체가 끝납니다.</li><li style="text-align:justify;">마지막으로, MSW를 적용하는 코드는 아래가 거의 전부입니다. (주의! 극단적인 예시입니다. 실제 적용 코드는 공식 문서에서 쉽게 확인하고 따라 할 수 있습니다.)</li></ul><p style="text-align:justify;"> </p><pre><code class="language-plaintext">// 모듈 불러오기 import { setupWorker, rest } from 'msw' // 핸들러 작성 및 Service Worker 셋팅 const worker = setupWorker( rest.post('/login', async (req, res, ctx) => { const { username } = await req.json() return res( ctx.json({ username, firstName: 'John' }) ) }), ) // Service Worker 실행 worker.start()</code></pre><p style="margin-left:0px;text-align:justify;"> </p><p style="text-align:justify;"> </p><h3 style="text-align:justify;"><strong>마무리</strong></h3><p style="text-align:justify;">저를 포함한 많은 웹 프론트엔드 개발자들은 API 개발에 대한 의존성으로 개발 경험이 저하되는 걸 경험했을 겁니다. 스트레스로 다가올 수 있는 상황을 매번 겪는 분도 계실 거고요. MSW를 도입하면 30분이라는 적은 시간을 투자해 더 좋은 방식으로 Mocking 할 수 있는 구조를 만들 수 있습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;">저의 경우 실제로 스프린트 기간에 MSW를 이용하니 API 개발에 대한 의존성이 낮아져서 병목을 많이 줄였고, 그 덕분에 개발 경험이 향상되었습니다. 이번 경험을 통해서 서비스 개발뿐만 아니라 개발을 잘할 수 있게 환경을 만들어 나가는 고민도 무척 중요하다는 걸 느꼈습니다.</p><p style="text-align:justify;"> </p><p style="text-align:justify;"><원문></p><p style="text-align:justify;"><a href="http://blog.hwahae.co.kr/all/tech/tech-tech/10195/">Mocking으로 프론트엔드 DX를 높여보자</a></p>