온비드 공매차량 검색 도구, 굳이 만들다 접은 개발 후기
시작은 단순하고 또 개발자다운 호기심이었습니다.
온비드에서 압류차량 공매 물건을 보다가 검색 필터가 손에 잘 익지 않았습니다. "제조사, 지역, 가격, 연식, 주행거리로 한 번에 필터링되는 똘똘한 검색 클라이언트를 하나 뚝딱 만들면 편하지 않을까?"
마침 공공데이터포털에 온비드 차량 공매 API도 오픈되어 있겠다, 주말 토요일 하루 정도면 충분히 MVP(Minimum Viable Product)를 뽑을 수 있을 것 같았습니다. 프론트엔드는 순식간에 완성했습니다. 반응형 검색창, 조건별 필터, 깔끔한 카드 UI, 다크모드 토글까지 — 여기까지는 개발하는 재미가 쏠쏠했습니다.
하지만 진짜 고행은 역시 API 연동 단계부터 시작되었습니다.
1. 공공데이터 API 연동의 국룰: 3대 삽질
화려한 UI 뒤에 실데이터를 붙이려니, 문서와 현실의 괴리 속에서 온갖 예외 처리를 마주해야 했습니다.
① 403 Forbidden — 알고 보니 키 오타
첫 호출부터 403이 떨어졌습니다. 트래픽 제한에 걸렸나, 활용신청 승인이 누락됐나 오만 가지 가설을 세우며 콘솔을 뒤졌는데, 원인은 허무했습니다. 서비스키를 .env에 옮겨 적는 과정에서 중간에 두 글자(Wu)가 통째로 빠져 있었습니다. 인증키 문자열이 워낙 길고 특수문자가 섞여 있어서 눈으로 디버깅하는 건 불가능에 가까웠습니다.
② "API 응답이 JSON이 아닙니다" (XML의 습격)
키를 복구하고 난 뒤에는 파싱 에러가 반겼습니다. 분명 요청 규격에 _type=json을 명시했음에도 불구하고, 쿼리에서 에러가 나면 무조건 XML 포맷으로 응답을 뱉어내고 있었습니다. "성공할 때만 JSON, 실패하면 XML"이라는 고오급(?) 예외 처리를 몸으로 체득하는 순간이었습니다.
③ NODATA_ERROR와 파라미터 네이밍의 함정
에러 메시지를 파싱해 원인을 추적하자 파라미터 체계의 문제가 드러났습니다.
응답 형식을 지정하는 필드명은
_type이 아니라resultType이었습니다. (다른 공공데이터 API들의 관례를 무심코 가져다 쓴 탓입니다.)prptDivCd(재산유형코드)에 대충 넣었던01같은 값은 존재하지도 않는 코드였습니다. 실제 유효값은0002(공유재산),0007(압류재산) 같은 4자리 코드였습니다.
결국 깃허브나 스택오버플로우를 뒤지는 것을 넘어, 구글 드라이브로 .docx 형식의 공식 API 활용가이드 문서를 직접 다운로드해 요청/응답 필드 스펙을 일일이 대조하고 나서야 비로소 데이터가 정상적으로 렌더링되기 시작했습니다.
2. 데이터는 띄웠는데, 비즈니스 로직에 구멍이 있다
고생 끝에 차량 리스트가 깔끔하게 출력되었지만, 한 가지 치명적인(?) 사실을 깨달았습니다. 상세 정보에 담당자 연락처나 문의처 필드가 아예 없었던 것입니다.
이유를 파악해 보니 당연했습니다. 온비드는 오프라인 전화 상담을 거쳐 입찰하는 구조가 아니라, 100% 온라인 전자입찰 시스템입니다. 회원가입, 공동인증서 등록, 온비드 공식 사이트에서의 입찰서 제출까지 모든 유저 플로우가 철저하게 온비드 플랫폼 안에서 완결됩니다.
여기서 문득 개발자로서 근본적인 아키텍처적 회의감이 밀려왔습니다.
"이거… 내가 만든 도구에서 상세 버튼을 누르면 결국 온비드로 링크를 꽂아주는 구조인데, 결국 온비드 트래픽 마케팅해 주는 꼴 아님?"
3. 아그리게이터(Aggregator) 관점에서 본 도메인 적합성
이 지점에서 가볍게 도메인 분석(Domain Analysis)을 돌려보았습니다. 정보성 서비스가 가치를 가지려면 "비교할 대안이 없는 파편화된 데이터"를 모아주는 아그리게이터 역할이 필수적입니다.
법원경매는 전국 각 지방법원이 독립적으로 물건을 공고하고 정보가 사방으로 흩어져 있습니다. 그렇기 때문에 민간 플랫폼(탱크옥션 등)이 여러 법원 데이터를 하나의 DB로 통합해 주는 것만으로도 엄청난 유저 락인(Lock-in) 효과와 유료 가치를 만들어냅니다.
반면, 온비드(압류재산·국유재산 공매)는 캠코(한국자산관리공사)가 법적으로 단일화한 국가 전자자산처분시스템입니다. 애초에 모든 공매 데이터가 온비드라는 단일 소스로 완벽하게 중앙화되어 있습니다.
즉, "파편화된 정보를 모아서 보여준다"는 아그리게이터의 핵심 가치가 이 도메인에는 애초에 비집고 들어갈 틈이 없었던 것입니다.
4. 왜 공공기관은 이런 API를 만들었을까?
마지막으로 남은 의문. "이렇게 단일 플랫폼으로 잘 돌아가는 시스템에 굳이 왜 이런 오픈 API를 파두었을까?"
답은 시장의 프로덕트 니즈가 아니라 컴플라이언스(Compliance)에 있었습니다. 「공공데이터의 제공 및 이용 활성화에 관한 법률」에 따라 공공기관은 보유 공공데이터를 머신러닝이나 외부 서비스가 활용할 수 있는 형태(Machine-readable)로 오픈할 법적 의무가 있습니다. 웹페이지(HTML) 제공만으로는 이 기준을 충족하지 못합니다.
즉, 이 API는 실무 개발자들의 사용자 경험 개선 목적이라기보다는, 국가 기관의 오픈 데이터 개방 평가지표와 법적 의무를 준수하기 위해 빌드된 성격이 강했습니다.
결론: 프로젝트는 롤백(Rollback), 하지만 남은 자산
코드 자체는 완성도 있게 뽑았습니다. 상태 관리도 잘 되었고, API 페이징과 필터링 로직도 매끄럽게 돌았습니다. 하지만 "이 프로덕트가 사용자에게 진짜로 해결해 주는 페인 포인트(Pain Point)가 무엇인가"에 대해 답을 내리지 못한 채, 과감하게 레포지토리를 닫기로 했습니다.
실패한 프로젝트처럼 보일 수도 있지만, 개발 과정에서 얻은 인사이트는 값집니다.
Idea ➔ Prototype ➔ API Integration ➔ Product-Market Fit (PMF) 검증 ➔ Pivot / Drop
수개월 동안 고도화에 집착하다가 뒤늦게 깨닫는 것보다, 주말 하루 동안 딥다이브해서 아키텍처와 도메인을 검증하고 빠르게 드롭하는 게 훨씬 효율적인 리소스 관리입니다.
이번 삽질을 통해 체득한 공공데이터 API 연동 노하우, 복잡한 문서 파싱 전략, 그리고 프로덕트를 기획하기 전 "정말 파편화된 도메인인가?"를 먼저 검증하는 시각은 다음 프로젝트의 훌륭한 밑거름이 될 것입니다.
다음에는 진짜로 API가 절실하게 파편화된 도메인을 타겟팅해서 제대로 된 툴을 빌드해 봐야겠습니다.