B2B 회사에서 프론트엔드 개발자로 일한지 3년이 되어가고 있다. 입사 초기, 나는 크게 두 가지 목표를 가지고 있었다.
지금 와서 돌이켜보면, 이 목표들은 꽤 단순하면서도 깊이 있는 의미를 품고 있었다. 기능 하나를 만들더라도 "이게 정말 유용한 기능일까?", "우리 서비스의 방향성과 맞을까?", "유저가 직관적으로 사용할 수 있을까?" 등을 끊임없이 고민하게 됐다. 이런 고민은 개발자 혼자만으로 해결할 수 있는 일이 아니기에, 기획자, 디자이너, 마케터 등 다양한 직군의 동료들과 자주 소통하면서 점차 내가 그리는 '완성도'의 범위를 넓혀갔다.
프론트엔드 관점에서의 완성도란, 단지 UI가 예쁘고 깔끔하다는 것에 그치지 않는다. 안정적인 서비스 운영이 가능해야 한다. 이를 위해 유지보수 하기 좋은 코드, 버그를 최소화 하기 위한 전략, DX를 향상을 통해 업무 효율 증가 등이 중요하다. 우리 팀은 이런 부분들을 점차 개선해 왔고, 나름 안정적으로 변하는 서비스를 보며 애정을 가지고 일하게 됐다.
두 번째 목표도 나름 절반 이상은 이룬 것 같다. 함께 일하는 선배 개발자들의 코드도 많이 봤지만, 단순히 코드를 보는 걸 넘어 "왜 그렇게 설계했는지", "이 선택의 배경에는 어떤 경험이 있었는지" 를 자주 질문했다. 사실 귀찮을법도 한데, 잘 대답해주신 덕분에 과거보다 넓은 시야로 일할 수 있게 된 것 같다. 이제는 나보다 저연차의 동료 개발자도 계시는데, 그 분에게도 배울점이 있다면 모두 받아들이고 있다.
이렇게 평화로운(?) 프론트엔드 생활을 하고 있던 와중에 새로운 업무가 하나 생겼다. 다른 팀에서 운영 중인 Web SDK의 유지보수와 기능 개선을 맡아줄 프론트엔드 개발자가 필요해진 것이다. 당시 Web SDK는 정리되지 않은 레거시 코드, 부족한 문서화 등으로 인해 누구나 선뜻 맡기엔 부담이 있었다. 그러던 중 팀 리더가 나에게 조심스레 제안하셨다.
“SDK는 안정성이 정말 중요한데, 잘 해줄 것 같아서 제안해본다.”
단순히 믿음에서 나온 말일 수도 있고, 그냥 내가 잘 받아들일 것 같아서 제안해주신 것일수도 있따. 어쨌든 나는 고민 끝에 아래와 같은 이유로 수락했다.
"SDK라는 걸 직접 경험해보면 재미있을지도 모르잖아?"
"이걸 맡게 되면, 우리 서비스의 메커니즘을 훨씬 깊이 이해할 수 있을 것 같아."
이렇게 해서, 나는 지금도 프론트엔드 개발자로 일하면서 Web SDK 업무를 겸하고 있다. 정확히 말하면 겸직이다. SDK 회의도 모두 참여하고, 유지보수도 하고, 기능 개선도 하고 있다. 초반에는 코드를 이해하기 위해서 많이 살펴보고, 버그가 올라오면 핫픽스 처리하고, 새로운 피쳐가 들어오면 기능을 추가하기도 했다. 지금은 어느정도 안정기에 들어서, 프론트와 Web SDK 업무 비율로 치면 9:1 정도 되는 것 같다.
서비스 하나를 만든다는 건, 단순한 일이 아니다. 사이드 프로젝트 하나를 만드는 데에도 많은 노력과 시간이 들어간다. 그래서 그런 프로젝트를 완성하고 나면 누구나 이렇게 생각하게 된다.
"많은 사람들이 이 서비스를 써줬으면 좋겠다."
이 바람은 개발자만의 것이 아니다. 기획자, 디자이너, 마케터 등, 그 서비스를 함께 만든 모든 사람들의 공통된 마음일 것이다. 누군가가 꾸준히 사용해주고, 피드백을 통해 서비스가 점점 더 좋아지는 걸 보면 엄청난 동기부여가 된다. 심지어 거기서 소소하게 수익까지 발생한다면, 이보다 더 뿌듯한 일은 없을 것이다.
하지만 회사에서 만드는 서비스는 이보다 더 현실적이다. "많은 사람들이 써줬으면 좋겠다"가 아니라, "많은 사람들이 반드시 써야만 하는 서비스"가 되어야 한다. 이를 위해 사업팀은 파트너사를 영업하거나, 마케팅팀은 온·오프라인 캠페인을 진행한다.
그런데, 유저가 유입됐다고 모든 게 끝난 건 아니다. "어떻게 하면 유입된 유저가 서비스를 오래 머무르고, 자주 사용하게 만들까?" 라는 의문이 진짜 중요한 포인트다. 그래서 많은 서비스가 유저의 행동 데이터를 수집하고, 분석한 뒤, 그에 맞는 마케팅 액션을 실행하려고 한다. 예를 들어, 이커머스 서비스를 생각해보자.
→ 이런 정보를 기반으로, 리타겟팅 광고를 집행하거나, 묶음 상품을 제안할 수 있다.
→ 이 유저에게는 해당 상품에 대한 할인 쿠폰이나 리뷰 이벤트를 노출할 수 있다.
→ ‘장바구니에 남아있어요’ 알림을 보내거나, 관심상품으로 분류해 맞춤 마케팅을 할 수 있다.
→ 또는 이탈율을 분석해 UI/UX 문제를 개선할 수도 있다.
이처럼 유저 행동 데이터를 기반으로 하면, 훨씬 정교한 마케팅 전략을 세울 수 있다. 그리고 우리 팀은 바로 이런 걸 도와주는 MMP/CRM 솔루션을 만들고 있다. 그렇다면 이런 기능들을 가능하게 해주는 가장 기본적인 도구는 무엇일까? 바로 SDK다.
내가 만든 서비스를 홍보하거나, 유저의 행동 데이터를 분석해 제품을 개선하고 싶을 때, 흔히 MMP(모바일 측정 파트너)나 CRM 마케팅 플랫폼을 떠올리게 된다. 그런데 이런 서비스를 도입한다고 해서, 갑자기 마법처럼 유저 데이터가 수집되는 건 아니다. 결국 유저의 행동 데이터는 서비스 내부에서 수집해야 하고, 그 접점에 놓이는 것이 바로 SDK다.
SDK는 안드로이드, IOS, 유니티, 플러터 등이 있고, 나는 그 중에서도 Web SDK를 담당하고 있다.
// 유저 정보 설정
example.setUser({
id: 'user-123',
gender: 'female',
age: 25,
});
가장 먼저 필요한 것은 데이터를 "쌓는" 행위다. 예를 들어, 유저가 웹사이트에 회원가입을 한다고 해보자. 이 순간 유저의 이메일, 연령대, 성별 같은 정보를 마케팅에 활용할 수 있게 동의하에 저장하고 싶어진다. 그럴 때 SDK는 다음과 같은 인터페이스를 제공한다.
// 유저 행동 기록
example.event('상품_클릭', {
productId: 'prod-456',
category: '화장품',
});
이후 유저가 어떤 행동을 할 때마다 이벤트를 기록할 수 있다. 페이지 방문, 버튼 클릭, 상품 조회, 결제 등은 모두 마케팅 관점에서 중요한 데이터가 된다.
이런 식으로 SDK를 통해 데이터를 정형화된 형태로 쌓아야만, MMP/CRM 대시보드에서 실시간 분석이 가능해진다. 예를 들어 게임사라면 로그인, 레벨업, 과금, 게임 종료 같은 액션들이 주요 이벤트가 된다. 마케터는 이런 데이터를 기반으로 유저 세그먼트를 나누고 전략을 짤 수 있게 된다. 이렇게 SDK에서는 직접 이벤트를 쌓도록 인터페이스를 제공하고 있지만, 유저가 앱을 실행하고 종료한 기점을 분석할 수 있도록 도와주는 세션 관리나 유입 분석 등을 위해 내부에서 자동으로 기록하는 것들도 있다.
두 번째 역할은 마케팅 캠페인의 전달자 역할이다. CRM 플랫폼에서는 유저 세그먼트를 기반으로 다양한 캠페인을 설계할 수 있다.
하지만 마케터가 캠페인을 설계했다고 해서 유저에게 자연스럽게 노출되는 것은 아니다. 앱이나 웹 페이지 상에서 이런 메시지를 보여주는 일은 결국 SDK가 해야 할 일이다. A 제품을 구매하는 경우, example.event(A구매)
을 통해 유저 행동을 기록할 것이다. SDK에서는 CRM 서비스에서 만들었던 캠페인 정보를 가지고 있는데, A구매
라는 이벤트로 트리거되는 캠페인이 있으면 노출시키는 것이다. SDK는 유저에게 언제, 어떤 형태로 메시지를 노출해야 할지 판단하는 로직과 렌더링 UI 컴포넌트를 함께 제공해야 한다.
현재 우리 팀에서 제공중인 MMP나 CRM 웹 서비스에서도 우리의 SDK를 심었다. 이제 이 서비스를 이용하는 유저들이 어떤 기능들을 많이 사용했는지, 어느 부분에 많이 머물렀는지 분석할 수 있다. 심지어 서비스의 기능 추가나 핫픽스 처리할 때마다, 우리 서비스에서 CRM 캠페인을 하나 만들어 어떤 기능들이 릴리즈 되었는지 고객들에게 모달과 같은 공지형태로 제공해줄 수도 있다.
최근에는 웹이나 앱에서 멀티 이미지 인앱 메시지를 지원하는 기능을 구현했다. Web SDK의 작업도 있었지만, 인앱 메시지는 네이티브(IOS, Android)에서도 웹뷰로 보여줘야 해서 다소 까다로웠다. 나는 먼저 모든 디바이스에서 동작할 공통 템플릿, UX를 위한 로직, 스타일 등을 설계했다. 그 후에 실제로 테스트해보면 Web에서는 정상적으로 동작 했다. 하지만 Android 혹은 IOS에서는 스타일이 깨진다거나 혹은 IOS에서만 드래그를 통한 캐러셀 동작이 막히는 등의 여러가지 문제에 직면했었다. 웹뷰라는것도 처음이었기에 모든 부분을 하나하나 디버깅해가면서 해결했던 것 같다.
Web SDK를 넘겨받자마자 히스토리와 코드들을 파악했다. 그리고 가장 먼저 한것이 관심사 분리다. 하나의 파일에 수 많은 코드들이 엮여 있었고, 전혀 다른 역할의 기능들이 한 곳에 모여있어서 도저히 유지보수 할 자신이 없었다. "하나의 함수는 하나의 기능"이라는 완벽한 관심사 분리는 할 수 없었지만, 그래도 하나의 파일에 수 많은 기능들이 모여있는 것은 해결했다. 이후에는 함수에 리턴 타입을 명시해주었고, 테스트 코드를 추가했으며, 더 확장성 있고 유연한 테스트 페이지도 구성했다.
로컬에서 수동 배포하던 부분을 GitHub Action을 통해 자동화했다. 이제 develop 혹은 main 브랜치에 풀리퀘스트 머지가 되면, 자동으로 develop 혹은 prod 빌드 후에 배포가 된다. 브랜치에 현재 배포된 develop와 prod 위치에 태그를 남기고, prod 배포의 경우에는 package.json
에서 가져온 버전으로도 태그를 생성하고 있다.
가장 힘들었던 것 중 하나가 제대로 된 문서가 없었다는 것이다. 그래서 나는 다음 사람들을 위해 문서화를 열심히 해야겠다는 생각으로, 굉장히 체계적으로 작성하기 위해 노력했다. 항상 느끼는 거지만 문서화를 한다던가, 아니면 내가 개발한 것을 바탕으로 글을 한 번 써보면 한 단계 더 성장 할 수 있는 것 같다.
프론트엔드 개발자 입장에서 SDK는 뭔가 낯설고 복잡한 도구처럼 느껴질 수 있다. 나도 그랬다. 뭔가 되게 로우레벨 API 같기도 하고, 딱 봐도 안정성이 중요하니까 손대기 무서운 느낌이었다. 근데 막상 직접 맡아보니까, SDK도 결국엔 하나의 ‘라이브러리’다. 라이브러리인데, 데이터 수집, 마케팅 메시지 노출 등 서비스 전반에 걸친 역할을 하는 녀석이라고 보면 된다. (서비스 품질과 직접적으로 연결된 미들웨어같기도 함)
일의 난이도는 확실히 올라갔다. 업무의 양이 증가한것도 있지만, 봐야하는 스펙트럼이 넓어지다보니 신경써야 하는 부분들이 많아졌다. 그래도 코드를 리팩터링 해 나가고, CI/CD도 구축하고, 새로운 기능들을 구현할때의 쾌감은 있다.
프론트엔드 보다 조금 더 어려운 부분은 딱 하나가 있다. 물론 다른 분야에서도 버그가 있으면 안되지만, 특히나 SDK는 버그가 터지면 매우 크리티컬하다. 이벤트가 수집되지 않거나, 이벤트가 잘못 수집되거나, 이벤트를 위한 캠페인들을 만들었는데 유저들에게 나타나지 않는 등의 버그가 터지면 고객들의 불만이 매우 클 수 밖에 없기 때문이다. 그래서 테스트 코드를 꼼꼼하게 작성하거나 테스트 페이지 같은 것을 잘 만들어두어야 한다.