쿠팡파트너스 검색 API 사용 중 쿼터 제한(시간당 10회)과 가격 필터링 미지원 문제를 경험하고 실시간 추천 구조에서의 외부 API 한계를 체감한 하루였다.
쿠팡파트너스 OpenAPI의 상품 검색 기능을 추천 시스템에 적용하던 중 다음과 같은 예상치 못한 제한 사항과 기능 제약을 경험했다. 처음에는 공식 문서 기준으로 분당 50회 제한이라 명시되어 있었기 때문에 이를 넘지 않으면 문제없다고 생각했다.
그런데 상품 추천 기능을 개발하다 어느 순간 부터 호출 로그는 찍히는데 정작 호출되는 상품들이 안찍혔다. 그래서 "도대체 왜 안가져오는 거지?"라는 의문을 품게 되었고 설마 API 호출 제한에 걸려서 안되는 건가를 생각을 하게 되었다. 그래서 직접 응답 바디를 출력해보니 24시간 API 제한에 걸리게 되었다.
JsonNode root = objectMapper.readTree(body);
String code = root.path("code").asText();
String message = root.path("message").asText();
JsonNode productData = root.path("data").path("productData");
log.info("code={}, message={}", code, message);
그렇게 또 한가지 의문이 생겼다. "분명 1분에 50회 이상으로 호출한 적이 없는데 왜 안되지"하면서 계속 찾아보게되었다. 공식 문서에서는 분당 50회까지만 명시되어 있었지만 실제로는 다르게 적용한다는 걸 아래 블로그를 보고 알 수 있었다.
이 블로그를 보니 검색 API는 시간당 10회로 제한되어 있었다.
403 FORBIDDEN
에러 발생 (ex. "rCode": "403"
)난 공식 문서만 보고 "분당 50회만 안넘기면 되겠지"란 생각으로 개발하고 있었던 것이다. 현재 개발 중인 추천 서비스의 방향은 키워드 리스트를 요청 받고 -> DB 캐싱 후 있다면 반환 -> 없다면 검색 API 호출 후 반환
이었지만 제한 사항에 때문에 방향성을 바꿔야한다는 생각이 들었다. 그래도 늦지 않게 알아서 프로젝트 방향을 수정해야된다는 걸 알 수 있었고 해당 부분은 팀원분들과 다시 얘기해볼 생각이다.
/product/search
API는 keyword 기반 검색만 가능하고 가격 필터링에 대한 파라미터를 지원하지 않는다.
상품 추천 서비스에서 예산을 키워드로 받기 때문에 그 예산에 맞게 가격 필터링을 해줘야한다. 하지만 상품 검색 API로 키워드를 통해 받아오는 상품들을 가격이 랜덤하게 섞인 상품들이 나오게 되어서 예산에 맞는 상품이 없을 수 있다는 문제가 생겼다. 그래서 실제 쿠팡 사이트로 가서 가격 필터링을 적용한 후 URL을 살펴봤다. 거기서 ...&minPrice=가격&maxPrice=가격...
이렇게 되어있는 걸 보고 minPrice
, maxPrice
파라미터를 쿼리에 추가해서 검색 API에 요청을 보내도 API는 해당 파라미터를 무시하고 여전히 가격이 뒤섞인 상품 리스트를 반환했다.
GET /v2/providers/affiliate_open_api/apis/openapi/v1/products/search?keyword=캠핑&minPrice=50000&maxPrice=100000
위와 같이 요청했지만 응답 결과에는 여전히 50,000원 미만 혹은 100,000원 초과 상품들도 포함되어 있었다. 이 과정에서 쿠팡파트너스의 검색 API는 실제 쿠팡 웹에서 사용하는 UI 필터와는 완전히 별개의 시스템이라는 것과 가격, 정렬 등 필터링 파라미터는 지원하지 않는다는 걸 알게 되었다.
이번 이슈를 통해 쿠팡파트너스 검색 API는 실시간 추천 시스템에 그대로 적용하기에는 한계가 분명하다는 점을 확인했다. 이에 따라 다음과 같은 구조 개선 방향을 도출했다.
현재 검색 API가 시간당 10회라는 제약을 가지고 있기 때문에 이를 활용한 사전 캐싱 구조로 방향을 전환했다. 매일 새벽 시간대에는 내부에서 정의한 대표 키워드 그룹에 대해 cron 작업을 통해 미리 상품을 수집하고 DB에 적재하는 전략을 적용해볼 예정이다.
노트북 서버는 상시 켜두고 백그라운드에서 돌아가는 Spring Scheduler 또는 Crontab을 활용하여 1시간에 9번 정도 API를 호출하며 키워드 리스트를 순회하면서 상품 정보를 확보한다.
(※ 10회 중 1회는 예외 상황 대비 여유 호출량으로 남겨둔다.)
이후 수집 대상 키워드는 다음과 같은 기준으로 구성할 계획이다.
이렇게 적재된 상품들은 이후 사용자 추천 요청이 들어왔을 때 실시간 호출 없이 DB에서 즉시 조회 및 필터링이 가능하게 되고 API 호출 쿼터 초과에 대한 리스크도 최소화할 수 있게 된다.
이번 경험을 통해 공식 문서만으로는 충분하지 않다는 점을 다시 한 번 깨달았다. API 연동을 할 때는 반드시 테스트 케이스를 다양하게 돌려보면서 실제 동작을 확인해야 하며 특히 외부 API는 내부 구현이 달라지거나 명시되지 않은 제한이 많기 때문에 방어적인 설계가 필요하다. 또한 실시간 추천을 지향하는 시스템이라 하더라도 외부 의존성이 강할 경우에는 캐시, 비동기, fallback 구조를 미리 설계해두는 것이 필수라는 점도 몸소 체감하게 되었다. 이번 이슈를 계기로 전체 서비스 구조를 점검하고 팀원들과 논의하여 보다 안정적이고 유연한 추천 흐름을 다시 설계해나갈 계획이다.