header_logo

COLDSURF BETA

#Refactor

Korean

Written by Paul

August 31, 2025

Photo by Umanoide on Unsplash
Photo by Umanoide on Unsplash

달리는 자동차의 바퀴를 교체한다고?

필자의 정성적 측면에서의 지난 6개월 회고인 다시 신입의 마음으로, 6개월은 정말 정성적인 측면에서만 회고를 다루어 보았다. 그렇다면, 이번에는 커리어 측면에서 내가 했던 일을 고민 대신 분석해보려 한다.
처음 면접을 보았을때에, 나는 다음과 같은 질문을 했다.
“제가 들어가게 되면 어떤 기대치를 충족하면 좋을까요?”
답변은 다음과 같았다.
“달리는 자동차의 바퀴를 안전하게 교체하는 일을 하신다고 생각해주시면 됩니다.”
듣고 다음과 같은 생각이 들었다.
“오오.. 재밌겠는데?”
이유는 다음과 같았다.
회사에 속한 개발자는 결국 회사가 지불해주는 임금을 받고, “기술서비스”를 제공하는 역할이다. 관련하여 좋은 영상인 [re:COMMIT] 비즈니스 마인드를 가진 개발자가 되는 방법을 한번 봐보는 것도 추천한다.
Video preview
 
다시 글로 돌아와서 “달리는 자동차의 바퀴를 교체한다”니, 내가 제공할 수 있는 기술 서비스 중 가장 매력적인 카테고리에 속한 것 같기도 하다. 하지만 당시에는 이처럼 까다롭고, 애매하고, 고될지 예상하지는 못했다. 단지 모든것이 나의 손이 닿으면 잘될 것이라는, 행복한 상상의 나래를 펼쳤던 것 같다. 무언가 개발자 컨퍼런스 영상에서 자주 볼 법한 “달리는 자동차의 바퀴를 교체”하는 일이 멋져보였던 것 같다.
이어지는 글에서는 내가 어떠한 “기술 서비스”를 제공했는지 적어보겠다.

낡은 빌드 시스템 교체

이전 회사에서부터 GitHub에서 제공해주는 Self Hosted 방식의 빌드 시스템에 관심이 많았다. 빌드 시간에 따라 비용은 부과되지 않되, 회사에서 제공하는 좋은 맥북을 활용할 수 있다면 빌드 시간도 많이 감소했기 때문이다.
회사에 들어와보니, 빌드 시스템의 상태가 다음과 같았고 해당 부분에 대해 개선이 가능할 지 요청을 받았다. (온보딩 단계라서, 히스토리를 알지 못하기 때문에 팀 리드나 오래 근속하셨던 분들이 개선해주었으면 하는 부분을 몇가지 구두로 알려주셨다.)
  • iOS 빌드를 무조건 로컬 맥북 빌드를 통해서 하고 있다. → 개선해줘
이전 회사에서도 Fastlane과 match를 통한 인증서 인증 + Self Hosted를 통한 iOS 빌드 자동화를 해본 경험이 있기 때문에, 그리 어렵지 않게 서비스를 제공해줄 수 있을 것이라고 생각했다.
해당 요구사항을 반영하여 내가 결과적으로 해낸 작업은 다음과 같았다.
  • iOS 빌드 시스템 원격으로 자동화 지원 ✅
  • Android 빌드 시스템도 사내 빌드머신으로 Self Hosted 기반 자동화 지원 ✅
  • 다수의 RN을 쓰는 레포에서 해당 빌드 GitHub action을 추상화하여 Reusable Workflow로 예쁘게 말아 지속가능성 및 재활용성 확보 ✅
이 정도의 서비스를 제공하고 나니, 주변 동료들이 어렵지 않게 빌드를 내놓는 모습을 보면 어느정도 개선이 됨을 몸소 체감할 수 있었다.
기존 로컬에서만 빌드 해야했던 iOS 빌드시스템도 개선이 되었고, 그로인해 Android 빌드시스템도 사내 빌드머신과 깃헙 러너를 통해 동시에 돌릴 수 있게 되었으며, 다수의 RN을 사용하는 레포에서 쉽게쉽게 이식가능한 형태의 FE 전용 Reusable Workflow 레포지토리를 만들어 재활용이 가능해졌으니 말이다.

API 페쳐 SDK 설계 및 적용

이건 사내에 굉장히 난제로써 남아있던 과제였는데, 문제상황은 추상적으로 다음과 같았다.
예를들어 가칭으로 서버에서 다음과 같은 형태의 데이터가 규칙을 가지고 내려온다고 해보자.
이런 구조에서 어떠한 fetch api를 쓰게 되느냐에 따라 데이터를 파싱하는 방법이 달라진다.
예를들어 누군가는 다음과 같이 생각할 것 이다.
  • “아니, 아무리 그래도 FE 개발자가 snake case를 쓰는게 말이 됩니까?” → “페치하는 라이브러리에 response interceptor 붙여서 camel case로 바꿔서 전달해버립시다!”
  • “아, 근데 .data.data 이런식으로 접근하기 귀찮은데..” → “이것도 response interceptor에 붙여서 미리 파싱해서 전달합시다!”
그 당시 이런 생각을 했던 분들은 지금 현재와 같은 스파게티 상황이 나올지 전혀 예상하지 못했던 것 같다.
자, 위의 생각들은 어떠한 나비효과를 불러일으켰을까?
  • 기본적으로 snake case로 내려왔던 서버데이터와 interceptor를 거쳐서 최종적으로 fetcher단에 전달된 데이터의 타입이 맞지 않는다. → camel case로 중간에 가로채기 되었기 때문에…
    • 따라서 이 부분은 react-query의 selector나 “as” 타입 연산자를 사용하여 타입을 강제시켜줘야 하는 문제가 발생했다 → 이렇게 되면 페쳐단에서 보일러 플레이트가 엄청 많아진다.
  • depth에 대한 파싱도 interceptor에서 처리 후 반환하기 때문에, 데이터 계층 구조에 대한 타입도 맞지 않았다
  • 그 상태에서 바쁘게 개발된 신규 앱들은 모두 다 다른 구조의 fetch response를 갖게 되었다.
    • 어떤 서비스의 페쳐부는 .data.data 로 파싱 했고, 어떤곳은 .data
    • 또한 DTO에 대해서 모두 서비스마다 다른 파편화된 구조를 가지고 있게 되었다. snake case, camel case 또한 일치하지 않았다.
결론적으로 타입스크립트 및 자바스크립트로 개발하던 코드베이스에서 서버데이터를 다루는 곳에 대한 안정성이 떨어지게 되었고, 필연적으로 난제로 남게 되었다.
이 난제는 결국 레거시로 이어졌고, 곳곳에 타입 강제가 묻어났으며 그 누구도 일원화된 DTO를 알고있지 않았다.
필자도 이 문제를 해결하기 위해 많은 고민을 했다. 근데 몇 가지 쉽게 머릿속에 추상화되는 부분은 존재했다.
  1. .data.data.data.data… 처럼 무수히 많은 .data를 파고들어가는 스트럭쳐를 typescript로 정적 타이핑화 가능할 것 같았다
  1. snake case ↔ camel case 간 전환은 오픈소스로도 많이 알려져있는 유틸들이 많았고, 실제 사내 util 라이브러리에도 가지고 있었던 유틸함수가 있었다
  1. 따라서 문제를 해결하려면 api sdk (즉, 페쳐 라이브러리)를 생성하는 시점에서 정적으로 리스폰스 타입만 잘 반환할 수 있도록 예측하여 타입을 맞추어주고, 중간 구현단계에서 for문 및 case util을 적용하여 실제 생성시점에서 적용된 설정에 따라 값을 잘 맞추어 반환하면 해결되는 문제였다.
 
자세한 내부 코드는 회사의 자산이므로 공개할 순 없지만, 결국 어느정도 DX를 해치지 않는 선에서 실제 프로덕션에도 적용할 수 있는 PoC 코드가 나오게 되었다.
이때에 타입스크립트의 infer와 tuple을 사용하여 정적으로 타입이 딱 맞아떨어지는 순간, “유레카!”를 외칠 수 밖에 없었다. 나름의 난제를 해결한 것이다.
관련해서 작성했던 블로그글이 있으니 관심이 있다면, 참고해봐도 좋을 것 같다.
 

API SDK를 개선하면서 느낀점

결론부터 정리하면 다음과 같다.
  1. 아무리 잘 만든 라이브러리가 있다하더라도, 실제 유저들이 사용하는가?는 다른 문제였다
  1. 그럼 회사측면에서 분석해 보았을 때, 다음과 같은 문제들이 존재했다.
    1. 기존 관성적으로 작성하던 방식을 모두 고수 할텐데, 개선된 라이브러리 커버리지를 어떻게 높일까?
    2. 챕터차원으로 규칙을 맞추기에는 아직 솔루션만 나온 단계이고 맞추어가야 할 텐데 커버리지가 높아졌을때 문제는 없을까?
결국 어느정도 인원이 있는 회사에서는, 단순히 개발자가 결과물만 내는것 뿐만 아니라, 소프트 스킬 및 적용 전략도 같이 고민해보아야 하는구나 라는 사실을 깨닫게 되었다.
관련해서 TOSS MAKERS CONFERENCE 25에서 기술 중심 엔지니어에서, 조직 중심 엔지니어로라는 세션이 있는 것을 보았는데 비슷한 고민을 담은 세션인 것 같아 영상이 공개되면 꼭 시청해 보고 싶다.
필자는 다음과 같이 홍보했다.
  1. “이거 쓰면 불필요한 보일러플레이트 줄어들어요!”
  1. 슬쩍 동료개발자에게 찾아가서, 썰을 늘어놓기…
결과적으로 팀원들 중 2-3명 정도는 관심을 보였고, 필자는 주기적으로 작은 프로젝트 위주로 api-sdk를 심어서 커버리지를 조금씩 높여갔다.
앞으로 커버리지가 높아질지는 미지수로 남아있다.

주력 앱 개선하기

필자는 엔지니어링 업무를 주로 보던 챕터 내 팀에서 있다가, 3개월 수습기간이 끝난 후 다시 피쳐를 개발하는 스쿼드로 조직변경이 되게 되었다.
여기에서 마주한 여러가지 문제점들은 기술적인 문제점들보다 훨씬 강력했다.
결국 프로덕트는 사람이 만드는 것이기에 소통에 대한 이슈들도 적지않게 경험하게 되었기 때문이다.
하지만 그 자세한 이야기는 회사차원의 일이므로, 여기에서 늘어놓을 순 없을 것 같다. 따라서 기술적인 측면에서 어떠한 서비스를 제공하고 있는지만 간략하게 적어보겠다.
  • 위에서 이야기한 API 인터셉터 구현부가 서로 다르게 합쳐진 여러 미니앱을 가진 구조의 앱이었다.
  • 따라서 미니앱 마다 api response 구조가 달랐다.
  • 또한 급하게 여러가지의 미니앱이 하나로 합쳐져서 만들어진 앱이다보니, 코드 안정성이 굉장히 떨어졌다.
    • 필자는 SI 혹은 외주개발의 코드도 가끔 경험했는데, 그보다 조금 나은 수준의 코드 안정성이었다. (개인적인 체감)
    • 따라서 어떤 새로운 피쳐가 들어가거나, 기존 리팩토링이 들어갈때에 코드단에서 기능에 대한 변경점을 알기가 너무 힘들었다
    • 그 짧은 기간에 몇 가지 HotFix를 유발하게 되었다
이러한 상황을 마주했을때 필자는 두가지 생각이 들었다.
  1. 아 그냥 나대지 말고, 다른 팀원분들처럼 조용히 코드 많이 건들이지 않고 개발만할까..
  1. 아니야! 그럴순 없지! 너는 기술서비스를 제공해야 하잖아!
1과 2, 그 중간에서 타협점을 찾아서 회사에도 도움이 되며 지속성을 가지면서 개선이 가능한 방법을 찾아 나서는 것이 내가 나름 내렸던 결론이었다.
이 과정에서 다음과 같은 사람측면의 문제들도 대두되었다.
  1. “주력앱인데, HotFix 많이 내지 말고 제발 기존에 개발했던 팀원분들과 말씀 좀 나눠가면서 하세요..”라는 피드백
  1. “나는 책임 못 지는데..” 에서 비롯된 리뷰의 부재 (이 부분은 명확한 코드오너가 없던 것도 문제였다)
  1. 먼저 물어보지 않으면, 즉 히스토리를 알수 없는 사람은 절대 알 수 없는 기능들. 즉 문서화의 부재
  1. 네이티브 배포를 기피하여, cherry-pick 위주의 배포로 생긴 형상관리 기술 부채
나름 압박으로 다가오긴 했는데, 나만의 낙관성을 바탕으로 “뭐 어쩌겠어? 아무도 개선하지 않았던 걸 처음 하는건데!” 라는 생각으로 꾸준히 개선을 하고있다. 필자는 스쿼드 피쳐개발도 해야했고, 아무도 시키지 않았던 개선작업도 해야 했다. 그래서 다음과 같은 로드맵을 잡고 개선해보고 있다.
  1. 문서화를 하자! (제발…)
    1. 사내 위키를 하나 만들어서 가볍게 여러 엣지케이스들에 대한 문서화를 남기고 있다
  1. 성능 개선 및 영속성 개선
    1. RN OldArch를 쓰는 앱이기 때문에, 곧 영속성이 금방 떨어질 것이다. 참고로 RN은 공식적으로 OldArch에 대한 deprecate를 선언했다. 더 이상 OldArch를 주력으로 개발해주지 않을 것이다.
    2. 따라서 일단 RN 최신화 하고 NewArch로 개선하는 작업을 진행했고, 아직 QA 리소스의 부재로 대기상태로 남아있다
    3. 최근에 오래 켜둘 시 앱이 너무 느려진다는 문의가 많이 들어왔다. 따라서 기존에 있는 코드 중 어떤것이 메모리 측면에서 누수를 일으키는지 파악하고 개선해보고 있다. (실제 출장도 갔다왔다)
  1. 배포 방식 개선
    1. 필자는 온보딩 과정에서 토스의 esbuild + OTA 방식을 모방하는 것을 해보는 온보딩 미션을 진행했다
    2. 따라서 주력앱이 여러 미니앱을 가지고 있으므로, 마이크로프론트엔드 구조와 함께 OTA 개선이 가능할 것이라고 생각했다.
    3. 누추한 방식이지만 나름 머리를 굴려보면서 고민해보고 있다. 실제 프로덕션단에서 적용이 가능한 구조의 PoC는 확보한 상태이다
    4. 관련해서 오픈소스로 내보여진 Granite 참고해보려 한다. (Thanks to toss…)
  1. 형상관리 이슈레이징
    1. 네이티브 변경점이 일어났을때, 해당 사항들만 쏙쏙 스킵하여 cherry-pick하여 배포하는 문화가 자리잡혀 있었다.
    2. 해당 부분은 RN개발을 해본 개발자라면 알겠지만, 필연적으로 형상관리 기술부채를 가져오게 된다.
    3. 이슈레이징 하였지만, 아무도 실질적으로 나의 마음을 알아주지는 못했다.
      1. 오히려 “네가 뭔데?”라는 반발감만 들었던 것 같다.
    4. 결국 release → release를 만드는 방식으로 운영중이다.
쭉 적어보았지만, 결국 해당 파트인 주력앱 개선이 가장 어려운 부분에 속하는 기술서비스 제공에 속하는 것 같다.
이유는 혼자서 개선하기에는 무리가 있기 때문이다. 결국 컨텍스트를 같이 하는 동료 개발자들의 지원이 필요한데, 컨텍스트를 같이 하기에는 모두가 큰 관심이 없어보인다. 또한 “나대지 않는 것이 좋다”라는 미학을 많이 시전하는 분위기라 앞으로 어떻게 개선을 해나갈지는 미지수다.

마치며

이 외에도 센트리 debugId 지원, CCTV 네이티브 모듈 개발 등 적지 않은 것들이 몇가지 있다. 모든 것을 다 적고 싶진 않았고 몇가지 내가 개선 작업을 반기동안 진행하면서 들었던 고민과 함께 같이 적어보았다.
결론적으로 반기동안 개선작업을 해보니 들었던 고민은 다음과 같았다.
“너무 예전에 했던거 반복하는것 같은데?”
Video preview
“시니어인지 아닌지 판단할때의 그 사람의 커리어의 묵직함을 봐요.”
결국 나의 커리어는 이전에 했던 작업만 돌려파는 그러한 고여있는 기술자가 되는 것이 아닌가?하는 고민이 들기 시작했다. 해당 부분을 개선하려면 회사의 지원도 필요하고, 여러 동료개발자들을 설득하는 리더쉽도 필요하다는 생각이 들었다. 무언가 큰 일을 하기 위해서는 결국 주변의 서포트가 필요하기 때문이다.
과연 나는 앞으로 묵직함이 있는 커리어를 가질 수 있을지, 두고 볼 일이다.
사실 이 글을 쓰기로 마음먹었던 것은 최근 토스 페이먼츠에서의 회고록을 공유해주신 김재민님의 미디엄 글 중 다음과 같은 단락을 보고 결정했다.
나는 20년+@ 된 엉망진창 시스템을 인수인계 받아서 (어느 정도) 정상화 레벨까지 올리는 경험을 해봤다
나의 비바리퍼블리카! — 토스 그리고 토스페이먼츠 여정기 라는 글에 더 자세한 내용은 나와있고 굉장히 흥미진진한 글이니 읽어보는 것을 추천한다! (개선을 하는 입장에서 정말 공감이 많이 되는 글이었다)
필자는 김재민님과의 나름 혼자만의 동질감 및 내적 친밀감을 느끼고 있었는데, 해당 글에서 더 많이 느껴졌다! (물론 실력에서 동질감을 느낀다는 것은 절대 아니다. 혼자만의 정성적인..)
마지막에 이러한 글이 나온다.
이번에 토스에 돌아가겠다는 그 이유는 당연히 동료들도 있지만, 오직 리더 때문이다
토스 팀에서 많은 동료가 나를 감동시켰지만, 내가 가장 많이 배웠고, 시야를 넓히고, 생각이 성장하는 데 영향을 가장 많이 준 동료는 토스 팀의 리더 승건님이다
퇴사를 결정하고도 얘기를 나눴는데, 오프보딩 까지 너무나 좋았고, 감사했고, 영광이었다
어쨌든 16년차 동안 10개의 법인를 다니며 이직을 많이 한 내가 한 회사에서 약 6년을 다녔고
필자도 이직을 굉장히 많이 한 편이다. 이곳저곳 돌아다니며 져니맨처럼 생활을 했다. 가장 오래다닌 회사가 채 2년이 안된다. 나도 언젠가 재민님처럼 나의 젊음을 리더에 대한 무한신뢰를 바탕으로 쏟아부을 수 있는 회사에 가보고 싶다.
 

© 2025 COLDSURF, Inc.

Privacy Policy

Terms of Service

Products