api-design

3 개의 포스트

끊김 없는 사용 경험을 위하여 : 카카오톡 선물함 속 교환권을 배달의민족 주문으로 연결한 여정 (새 탭에서 열림)

배달의민족 선물하기 팀은 사용자가 카카오톡으로 받은 브랜드 교환권을 배달의민족 앱에서 직접 등록하고 주문에 사용할 수 있도록 하는 '외부 교환권 연동 서비스'를 기획하고 구현했습니다. 이 프로젝트는 플랫폼 간의 기술적·비즈니스적 장벽을 허물어 사용자의 파편화된 구매 경험을 하나로 잇고, 외부의 잠재적 주문 수요를 배달의민족 생태계 안으로 흡수하는 것을 핵심 목표로 삼았습니다. 결과적으로 기술적 복잡성과 다자간의 이해관계를 극복하며 '끊김 없는 연결'이라는 사용자 중심의 가치를 실현해냈습니다. **사용자 불편 해소와 비즈니스 성장의 결합** - 카카오톡 선물을 사용하기 위해 브랜드 자사 앱을 새로 설치하거나 매장을 직접 방문해야 했던 고객의 페인포인트(Pain Point)를 해결했습니다. - 외부 플랫폼에 머물던 교환권 수요를 배달의민족 앱 내 주문으로 전환함으로써 신규 고객 유입과 락인(Lock-in) 효과를 도모했습니다. - 단순히 기능을 추가하는 것을 넘어, 플랫폼 경계를 확장하여 배달의민족을 모든 주문 경험의 통합 창구로 만들고자 했습니다. **플랫폼 간 장벽을 넘는 ‘연결’의 본질 정의** - 여러 조직이 참여하는 대규모 프로젝트에서 "플랫폼 간 장벽을 넘어 사용자에게 끊김 없는 연결을 제공한다"는 본질적인 목표를 설정하여 의사결정의 기준으로 삼았습니다. - 기술적 제약이나 비즈니스 수익성 등 이해관계가 충돌할 때마다 프로젝트의 본질을 자문하며 사용자 중심 사고를 유지했습니다. - 고립된 플랫폼 생태계를 연결함으로써 사용자에게 경험의 단절이 없는 새로운 가치를 제공하는 선례를 남겼습니다. **다자간 협업을 위한 맞춤형 소통 기술** - 카카오(플랫폼사), 브랜드사, 쿠폰 연동사 등 서로 다른 KPI를 가진 파트너들과 공통의 목표인 ‘고객 경험 개선’을 공유하며 협력을 이끌어냈습니다. - 백엔드 개발자에게는 API 응답 속도와 에러 핸들링을, 비즈니스 담당자에게는 제휴 조건과 정산 프로세스를 중심으로 설명하는 ‘맞춤형 언어’를 사용했습니다. - ‘등록·사용’(배민)과 ‘조회·승인’(연동사)처럼 서로 다른 도메인 용어와 로직을 꼼꼼히 동기화하여 시스템 간의 간극을 메웠습니다. **주도적인 문제 해결과 기술적 조율** - 단순히 요구사항을 전달하는 가교 역할을 넘어, 양사 기술팀이 합리적인 타협점을 찾을 수 있도록 API 스펙과 에러 대응 정책을 주도적으로 조율했습니다. - 다양한 외부 연동사의 시스템을 수용하면서도 배달의민족 내에서의 사용 경험을 표준화하기 위한 기술적 스펙을 정의했습니다. - 복잡한 의존 관계를 가진 작업들 사이에서 우선순위를 설정하고 일정을 관리하며 프로젝트의 항해사 역할을 수행했습니다. 이 프로젝트는 기술적 구현만큼이나 플랫폼 간의 심리적·비즈니스적 거리를 좁히는 과정이 중요함을 보여줍니다. 복잡한 시스템 연동을 앞두고 있다면, 기술 스펙에 매몰되기보다 '사용자에게 어떤 연결된 가치를 줄 것인가'라는 본질을 먼저 정의하고, 파트너의 언어로 소통하며 주도적으로 표준을 만들어가는 접근 방식이 필요합니다.

토스페이먼츠의 Open API 생태계 (새 탭에서 열림)

토스페이먼츠는 Open API를 단순한 통신 수단을 넘어 수십 년간 안정적으로 운영되어야 할 핵심 인프라로 정의합니다. 20만 개 이상의 가맹점이 사용하는 환경에서 개발자의 인지 부하를 줄이고 연동 신뢰성을 높이기 위해, 리소스 중심의 인터페이스 설계와 자동화된 생태계 구축을 최우선 과제로 삼고 있습니다. 이러한 철학은 기술적 완성도를 넘어 가맹점 개발자가 겪는 전반적인 경험(DX)의 질을 결정짓는 근간이 됩니다. ### 리소스 중심의 일관된 인터페이스 설계 * **직관적인 경로 규칙**: 가맹점이 URL 구조만 보고도 기능을 예측할 수 있도록 `버전/도메인/리소스 고유 ID` 순서의 일관된 경로 체계를 사용합니다. 특정 리소스 지정 외의 조건은 쿼리 파라미터나 JSON 필드로 분리하여 명확성을 높였습니다. * **중첩 객체를 활용한 모듈화**: 카드 정보나 현금영수증 내역처럼 여러 API에서 반복되는 데이터는 JSON의 계층 구조를 활용해 객체 형태로 모듈화합니다. 이는 데이터 중복을 줄이고 응답의 의미를 명확하게 전달하며, null 체크 등 가맹점의 코드 로직을 간소화합니다. * **도메인별 객체 재사용**: 승인, 조회, 취소 등 연관된 도메인의 API들이 동일한 응답 객체를 공유하도록 설계하여, 개발자가 새로운 API를 연동할 때 추가적인 학습 없이 결과를 예측할 수 있게 합니다. * **자연어 기반 데이터 표현**: 시스템 효율을 위한 코드 값(예: SC0010) 대신 "현대", "국민"과 같은 직관적인 한글 데이터를 제공합니다. 또한 `Accept-Language` 헤더에 따라 영문 등으로 응답을 자동 전환하는 로컬라이제이션(Localization)을 지원합니다. * **표준화된 오류 처리**: HTTP 상태 코드로 큰 틀의 성공/실패를 구분하고, 상세한 에러 코드와 메시지를 담은 표준 객체를 응답 바디에 포함하여 가맹점이 상황에 맞춰 유연하게 대응할 수 있도록 돕습니다. ### 비동기 처리를 위한 안정적인 웹훅 체계 * **이벤트 기반 처리**: 즉각적인 응답이 어려운 비동기 결제 상황에서 서버가 클라이언트에 처리 완료를 알리는 웹훅 인터페이스를 API와 함께 제공합니다. * **데이터 구조의 일관성**: 웹훅을 통해 전달되는 데이터 페이로드를 일반 API 응답과 동일한 리소스 객체 구조로 설계하여 가맹점의 파싱 로직 중복을 방지합니다. * **지수 백오프(Exponential Backoff) 재전송**: 네트워크 이슈나 가맹점 서버 장애로 인한 웹훅 전송 실패 시, 수신 서비스의 회복 시간을 고려하여 점진적으로 재시도 간격을 늘리는 전략을 사용합니다. * **자가 조치 도구 제공**: 개발자가 직접 웹훅 전송 내역을 조회하고 필요 시 수동으로 재전송할 수 있는 기능을 개발자 센터를 통해 지원하여 운영 편의성을 높였습니다. ### 개발자 경험(DX) 강화를 위한 문서 자동화 * **OAS 기반 실시간 동기화**: 수동 문서 작성의 한계를 극복하기 위해 OpenAPI Specification(OAS)과 Springdoc 라이브러리를 활용하여 서버 코드와 문서가 실시간으로 동기화되는 시스템을 구축했습니다. * **문서의 신뢰성 확보**: API 스펙이 변경될 때마다 연동 문서가 즉시 업데이트되므로, 가맹점 개발자는 항상 실제 동작하는 서버와 일치하는 최신 명세를 바탕으로 안심하고 개발할 수 있습니다. 토스페이먼츠의 사례처럼 좋은 Open API는 단순히 기능의 유무를 넘어, 개발자가 '설명 없이도 이해할 수 있는' 직관적인 구조와 자동화된 지원 환경을 갖추어야 합니다. 특히 리소스 중심 설계와 API-웹훅 간 데이터 일관성은 가맹점의 연동 비용을 획기적으로 낮추는 실용적인 전략이 될 수 있습니다.

API 호출식 웜업의 부작용을 넘어서 : 라이브러리만 데우는 JVM 웜업 (새 탭에서 열림)

JVM 기반 웹 애플리케이션은 실행 초기 JIT(Just-In-Time) 컴파일러의 최적화 과정에서 발생하는 응답 지연 문제를 해결하기 위해 '웜업' 과정이 필수적입니다. 기존의 API 호출식 웜업은 데이터 오염이나 외부 시스템 부하와 같은 부작용을 초래할 수 있으나, 본 발표에서는 이를 극복하기 위해 핵심 라이브러리만을 직접 예열하는 '라이브러리 웜업' 방식을 제안합니다. 이 기술을 통해 부작용 없이 애플리케이션 배포 직후의 성능을 안정적으로 확보할 수 있습니다. **JVM 웜업의 필요성과 기존 방식의 한계** * JVM은 실행 초기에 인터프리터 방식으로 동작하다가, 반복되는 코드를 JIT 컴파일러가 네이티브 코드로 최적화하는 과정을 거치며 성능이 올라갑니다. * 이 최적화가 완료되기 전까지는 응답 시간이 길어지거나 CPU 사용량이 급증하는 현상이 발생하므로, 실제 트래픽이 들어오기 전 코드를 미리 실행하는 웜업이 필요합니다. * 기존의 API 호출 방식은 가짜 요청을 보내는 과정에서 DB 데이터 정합성을 해칠 수 있고, 외부 API 호출에 따른 불필요한 연동 부하를 발생시키는 단점이 있습니다. **라이브러리 웜업의 핵심 아이디어와 구현** * 비즈니스 로직 전체를 수행하는 대신, 애플리케이션에서 성능 비중이 크고 공통적으로 사용되는 '라이브러리 코드'만을 타겟팅하여 예열합니다. * 예를 들어 JSON 파싱, 암호화, 복잡한 수치 계산 모듈 등 JIT 컴파일 임계치(Threshold)를 넘겨야 하는 핵심 메서드들을 반복 호출하도록 설계합니다. * 애플리케이션 시작 단계(Post-Construct 등)에서 비즈니스 로직과는 독립된 웜업 코드를 실행함으로써 데이터 오염의 위험을 원천적으로 차단합니다. **성능 검증 및 실무적 이점** * 라이브러리 웜업 적용 후, 배포 초기에 발생하는 응답 속도의 '튀는 현상(Spike)'이 현저히 감소하고 전체적인 레이턴시가 안정화됨을 확인했습니다. * API 호출 방식보다 구현이 단순하고 외부 의존성이 적어 관리가 용이하며, 배포 파이프라인의 안정성을 높이는 데 기여합니다. * 다만, 모든 비즈니스 경로를 커버하지는 못하므로 성능 영향도가 높은 핵심 모듈을 선별하여 집중적으로 웜업하는 전략이 유효합니다. 빠른 스케일 아웃이 필요한 마이크로서비스 환경이나 지연 시간에 민감한 실시간 서비스라면, API 기반 웜업의 대안으로 이와 같은 라이브러리 단위의 정밀한 웜업 도입을 적극 권장합니다.