Dida 외부 API 연동 정리

Published: by Creative Commons Licence

Dida 외부 API 연동 정리

Dida(디다) 외부 API를 연동하는 프로젝트의 API 목록 및 처리 프로세스를 정리한다.


프로젝트 구조 개요

  • 언어/프레임워크: Java / Spring Boot
  • HTTP 클라이언트: RestTemplate(Static), WebClient(Realtime)
  • 인증: ClientID + LicenseKey (Header에 포함, 설정 파일에서 관리)
  • Base URL 설정: channel.dida.webClient.baseUrl (application properties)

모든 Dida API 요청은 RequestUtils를 통해 공통 헤더(ClientID, LicenseKey)를 포함한 요청 Map을 구성해서 전송한다.


API 분류

전체 API는 크게 두 가지로 분류된다.

  • Static Data API (/api/static): 주기적(주 1회 등)으로 Dida 기준 데이터를 가져와 DB에 저장하는 배치성 API
  • RealTime API (/api/realtime): 호텔 검색, 예약, 취소 등 실시간 처리 API

1. Static Data API

컨트롤러: StaticDataController (/api/static)

1-1. 국가코드 업데이트

항목 내용
Endpoint POST /api/static/country-update
Dida API channel.dida.Api.CountryList
처리 요약 Dida에서 전체 국가 목록 조회 후 DB(dida_country) upsert

프로세스

  1. Dida CountryList API 호출 (파라미터 없음)
  2. 응답 JSON에서 Countries 배열 파싱 → List<CountryDto> 변환
  3. staticDataDao.updateCountryCode() 로 DB 일괄 업데이트

1-2. 도시코드 업데이트

항목 내용
Endpoint POST /api/static/city-update
Dida API channel.dida.Api.CityList
처리 요약 Dida에서 전체 도시 목록 조회 후 10,000건씩 분할 DB 저장

프로세스

  1. 요청 파라미터: IncludeSubCity: true
  2. 응답 JSON에서 Cities 배열 파싱 → List<CityDto> 변환
  3. 전체 목록을 10,000건 단위로 분할하여 반복 staticDataDao.updateCityCode() 호출
    • 데이터 규모가 크기 때문에 페이징 처리

1-3. 침대타입 업데이트

항목 내용
Endpoint POST /api/static/bedtype-update
Dida API channel.dida.Api.BedTypeList
처리 요약 Dida 침대타입 코드 목록 조회 후 DB 저장

프로세스

  1. Dida BedTypeList API 호출 (파라미터 없음)
  2. 응답 JSON에서 BedTypes 배열 파싱 → List<BedTypeDto> 변환
  3. staticDataDao.updateBedTypeList() 로 DB 업데이트

1-4. 숙소카테고리 업데이트

항목 내용
Endpoint POST /api/static/property-category-update
Dida API channel.dida.Api.PropertyCategoryList
처리 요약 숙소 유형(호텔/리조트 등) 코드 목록 조회 후 DB 저장

프로세스

  1. Dida PropertyCategoryList API 호출 (파라미터 없음)
  2. 응답 JSON에서 PropertyCategorys 배열 파싱 → List<PropertyCategoryDto> 변환
  3. staticDataDao.updatePropertyCategoryList() 로 DB 업데이트

1-5. 호텔 Static 정보 업데이트 (주 1회)

항목 내용
Endpoint POST /api/static/hotel-static-information
Dida API channel.dida.Api.HotelStaticInformation
처리 요약 약 수십만 건의 호텔 기본정보(HotelSummary) 신규 데이터만 DB insert

프로세스

  1. 요청 파라미터: IsGetUrlOnly: true, StaticType: "HotelSummary"
  2. Dida로부터 압축(gzip) byte 응답 수신 → JSON 파싱 → List<PropertyDto> 변환
  3. 1,000건 단위로 분할 후 MyBatis ExecutorType.BATCH로 고속 insert
    • sqlSessionBatchInsertProperties Mapper 사용
  4. 신규 숙소만 insert (upsert 아님)

1-6. 객실타입 업데이트 (주 1회)

항목 내용
Endpoint POST /api/static/room-type-information
Dida API channel.dida.Api.HotelStaticInformation
처리 요약 약 616만 건의 객실타입(RoomType) 신규 데이터만 DB insert

프로세스

  1. 요청 파라미터: IsGetUrlOnly: true, StaticType: "Roomtype"
  2. Dida 응답 파싱 → List<RoomTypeDto> 변환
  3. 1,000건 단위 분할 + parallel() 병렬 처리로 MyBatis Batch insert
    • 병렬 처리 적용 후 처리 시간 약 50% 단축 (순차 1,289초 → 병렬 593초)

2. RealTime API

컨트롤러: RealTimeController (/api/realtime)
HTTP 클라이언트: WebClient (비동기 논블로킹)

2-1. 호텔별 최저가 조회

항목 내용
Endpoint POST /api/realtime/search-property
Dida API channel.dida.webClient.PriceSearchList
처리 요약 자사 호텔코드 리스트로 각 호텔의 최저가 조회

프로세스

  1. 요청으로 받은 자사 호텔코드로 DB에서 Dida 호텔ID 목록 조회
  2. Dida API 제한(호텔 최대 50개/요청)에 따라 50개 단위로 분할
  3. Flux.parallel()로 분할된 목록을 병렬로 Dida PriceSearchList API 호출
    • 요청 파라미터: CheckInDate, CheckOutDate, Nationality, Currency: USD, LowestPriceOnly: true, IsRealTime.Value: false (캐시 데이터)
  4. 전체 응답 병합 후 호텔별 최저가(PropertyLowPriceDto) 리스트 반환
  5. 에러 응답이 있는 경우 전체 실패 처리

2-2. 호텔상세 객실요금 조회

항목 내용
Endpoint POST /api/realtime/search-rateplan
Dida API channel.dida.webClient.PriceSearchList
처리 요약 숙소 상세 진입 시 투숙정보 기반 객실별 요금 및 RatePlan 조회

프로세스

  1. 자사 상품 ID로 DB에서 Dida 호텔정보 조회
  2. Dida PriceSearchList API 호출 (단일 호텔, IsRealTime.Value: true — 실시간 조회)
  3. 응답 RatePlanList 처리 시:
    • 중국어 RatePlan 제외 (정규식 한자 필터링)
    • 당일 SearchBlock 테이블 기준으로 이전에 실패한 RatePlan 제외
    • InventoryCount >= 요청 객실수 조건 필터
    • RoomTypeID가 없는 RatePlan 제외
  4. 필터 통과한 RatePlan 목록 → RatePlanDto.SearchRoomRatePlan 변환 후 반환

2-3. 사전 예약 (PriceConfirm)

항목 내용
Endpoint POST /api/realtime/price-confirm
Dida API channel.dida.webClient.PriceConfirm
처리 요약 예약 전 최종 요금 확정 및 취소 규정 확인, ReferenceNo 발급

프로세스

  1. DB에서 호텔의 국가코드 조회 후 요청에 세팅
  2. dida_price_confirm_log 테이블에 요청 전 로그 insert
  3. Dida PriceConfirm API 호출
    • 요청 파라미터: CheckInDate, CheckOutDate, Nationality, Currency, PreBook: true, HotelID, RatePlanID, NumOfRooms, OccupancyDetails
  4. 응답 후 dida_price_confirm_log 업데이트
  5. 에러 응답 시: SearchBlock 테이블에 차단 정보 insert (당일 동일 조건 재검색 방지)
  6. 성공 시: 환율 정보 조회 → USD 가격을 KRW로 환산, ReferenceNo 저장 후 반환

2-4. 객실 예약 생성 (CreateBooking)

항목 내용
Endpoint POST /api/realtime/create-booking
Dida API channel.dida.webClient.CreateBooking
처리 요약 PriceConfirm에서 발급받은 ReferenceNo로 실제 예약 생성

프로세스

  1. dida_reservation_log 테이블에 요청 전 로그 insert
  2. Dida CreateBooking API 호출
    • 요청 파라미터: CheckInDate, CheckOutDate, NumOfRooms, ClientReference(자사 예약번호), ReferenceNo, Contact(예약자 정보), GuestList(투숙객 정보)
    • 투숙객 정보 없을 경우 예약자 정보로 대체
    • 전화번호에서 (+82)0 변환 처리
  3. 응답 후 dida_reservation_log 업데이트
  4. 에러 시: SearchBlock insert 후 실패 반환
  5. 성공 시 DB 저장:
    • dida_reservation (예약 메인 정보)
    • dida_reservation_guest (객실별 투숙객 정보)
    • dida_cancellation (취소 수수료 정책)
  6. dida_price_confirm_log에서 이전 PriceConfirm 응답을 조회하여 객실명, 최대인원 등 추가 정보 보완

2-5. 예약 취소 (CancelBooking)

항목 내용
Endpoint POST /api/realtime/cancel-booking
Dida API channel.dida.webClient.CancelBooking
처리 요약 예약 취소 요청 및 취소 수수료 확인, ConfirmID 발급 (유효시간 10분)

프로세스

  1. DB에서 해당 BookingID의 예약 상태(CONFIRMED) 확인
  2. dida_cancel_booking_log 테이블에 요청 전 로그 insert
  3. Dida CancelBooking API 호출 (요청 파라미터: BookingID)
  4. 응답에서 ConfirmID, 취소 수수료(Amount) 추출
  5. DB의 예약 정보에 cancelConfirmId 업데이트
  6. ConfirmID를 반환 (이후 cancel-confirm에서 10분 이내 사용 필요)

2-6. 예약 취소 확정 (CancelConfirm)

항목 내용
Endpoint POST /api/realtime/cancel-confirm
Dida API channel.dida.webClient.CancelConfirm
처리 요약 CancelBooking에서 받은 ConfirmID로 취소 최종 확정 처리

프로세스

  1. DB에서 BookingID 예약 상태(CONFIRMED) 확인
  2. dida_cancel_confirm_booking_log 테이블에 요청 전 로그 insert
  3. Dida CancelConfirm API 호출 (요청 파라미터: BookingID, ConfirmID)
  4. 성공 시 dida_reservationbooking_statusCANCELED로 업데이트

2-7. 예약 취소 + 취소 확정 통합 (CancelConfirmBooking)

항목 내용
Endpoint POST /api/realtime/cancel-confirm-booking
처리 요약 CancelBooking → CancelConfirm 을 순차적으로 한 번에 처리 (사용 권장)

프로세스

  1. cancelBooking() 서비스 호출
  2. 성공 시 응답의 BookingID, ConfirmID로 즉시 cancelConfirm() 서비스 호출
  3. 취소 + 확정을 단일 API 호출로 처리 가능하여 클라이언트 편의성 제공

2-8. 예약 조회 (SearchBooking - 자사 예약번호 기준)

항목 내용
Endpoint GET /api/realtime/search-booking/{internalBookingId}
Dida API channel.dida.webClient.SearchBooking
처리 요약 자사 예약번호로 DB에서 Dida BookingID 조회 후 예약 상세 반환

프로세스

  1. DB에서 자사 예약번호(internalBookingId)로 Dida BookingID 조회
  2. Dida SearchBooking API 호출 (SearchBy.BookingID 파라미터)
  3. 응답 BookingDetailsList[0] 파싱:
    • 예약 상태, 체크인/아웃일, 객실수, 투숙객 목록, 호텔 정보, RatePlan, 취소 정책 등 매핑
    • 날짜 포맷 변환: yyyy-MM-dd HH:mm:ssyyyy-MM-dd

2-9. 예약 조회 (SearchBooking - Dida BookingID 기준)

항목 내용
Endpoint GET /api/realtime/search-booking-didaID/{bookingId}
Dida API channel.dida.webClient.SearchBooking
처리 요약 Dida BookingID를 직접 입력받아 예약 상세 조회

2-8과 동일하나 DB 조회 없이 입력받은 ID를 Dida BookingID로 직접 사용


3. API 목록 요약

Static Data API (/api/static)

# Endpoint Dida API 설명 주기
1 POST /country-update CountryList 국가코드 업데이트 수시
2 POST /city-update CityList 도시코드 업데이트 수시
3 POST /bedtype-update BedTypeList 침대타입 업데이트 수시
4 POST /property-category-update PropertyCategoryList 숙소유형 업데이트 수시
5 POST /hotel-static-information HotelStaticInformation (HotelSummary) 호텔 기본정보 업데이트 주 1회
6 POST /room-type-information HotelStaticInformation (Roomtype) 객실타입 업데이트 주 1회

RealTime API (/api/realtime)

# Endpoint Dida API 설명
1 POST /search-property PriceSearchList 호텔별 최저가 조회
2 POST /search-rateplan PriceSearchList 호텔상세 객실요금/RatePlan 조회
3 POST /price-confirm PriceConfirm 사전예약 (요금확정, ReferenceNo 발급)
4 POST /create-booking CreateBooking 객실 예약 생성
5 POST /cancel-booking CancelBooking 예약취소 (수수료 확인, ConfirmID 발급)
6 POST /cancel-confirm CancelConfirm 예약취소 확정
7 POST /cancel-confirm-booking CancelBooking + CancelConfirm 취소+확정 통합 처리 (권장)
8 GET /search-booking/{id} SearchBooking 예약조회 (자사 예약번호)
9 GET /search-booking-didaID/{id} SearchBooking 예약조회 (Dida BookingID)

4. 주요 특이사항

SearchBlock (차단 목록)
PriceConfirm 또는 CreateBooking 실패 시 동일 날짜/호텔/RatePlan 조합을 dida_search_block 테이블에 기록한다. 이후 당일 RatePlan 검색 시 해당 항목을 결과에서 제외하여 불필요한 실패 반복을 방지한다.

병렬 처리
최저가 조회(search-property)는 Dida 호텔 50개 제한으로 분할 후 Flux.parallel()로 동시 호출하고, RoomType 배치 저장도 IntStream.parallel()로 병렬 insert한다.

환율 적용
Dida API는 USD로 응답하므로, PriceConfirm 이후 DB의 환율 정보(dida_ex_rate)를 조회해 KRW 환산 금액을 함께 반환한다.

인증
모든 요청의 Body에 Header: { ClientID, LicenseKey } 포함 (RequestUtils.getNotHttpEntity() / getHttpEntity()). 인증 값은 설정 파일에서 관리한다.