[BE-05] 에어코리아 Gateway 구현 — 3단계 체인 + Redis 캐시 + graceful degrade
작업 내용 (설계 의도)
변경 사항
에어코리아 3단계 API 체인을 단일 Gateway 뒤로 캡슐화하고, 측정 결과를 Redis에 캐시해 500/day 한도·P95 1.5초를 보호한다. BE-03의 계약을 구현한다. 근거 TDD: ../TDD.md FR-8·FR-10·“방안 비교 대기질 캐싱”.
infrastructure/airquality/gateway/AirQualityProperties.kt—@ConfigurationProperties("external.air-quality")(base-url + api-key).application.yml—external.air-quality블록 추가(base-url${EXTERNAL_AIR_QUALITY_BASE_URL:http://localhost:9102}, api-key${DATA_GO_KR_SERVICE_KEY:mock-service-key}). 이 wave에서 application.yml 단독 수정자.infrastructure/airquality/gateway/AirKoreaAirQualityGatewayImpl.kt—ExternalRestClientFactory로 RestClient 생성.current(lat,lng): 그리드키(lat·lng 소수 3자리) 캐시 조회 → 미스 시 getTMStdrCrdnt → getNearbyMsrstnList → getMsrstnAcctoRltmMesureDnsty 순 호출 → measurement 캐시 저장. Client DTO는 infra에 위치,@JsonIgnoreProperties.ConsumerRecord아님/LocalDateTime금지(ZonedDateTime). 임의 단계RestClientException·타임아웃·빈응답 →AirQualityMeasurement.empty().infrastructure/airquality/redis/AirQualityRedisCache.kt—AirQualityMeasurementCache구현.StringRedisTemplate+ ObjectMapper(기존PopularProductsRedisRepository패턴). 키airquality:measurement:{gridKey}, TTL 10분 + jitter. Redis 장애 시 캐시 skip.
롤백
- 실연동 → env를 mock host로 되돌려 재기동(즉시). 기능 전체 → 컨트롤러 미노출.
의존
- BE-03
다이어그램
처리 흐름
sequenceDiagram participant S as AirQualityDomainService participant G as AirKoreaGatewayImpl participant K as AirQualityRedisCache participant A as 에어코리아 API S->>G: current(lat,lng) G->>K: findBy(gridKey) alt 미스 G->>A: getTMStdrCrdnt→getNearbyMsrstnList→getMsrstnAcctoRltmMesureDnsty A-->>G: pm10,pm25 (or 실패) G->>K: save(gridKey, measurement) end G-->>S: measurement (or empty)
클래스 의존
flowchart LR Impl[AirKoreaGatewayImpl] --> Props[AirQualityProperties] Impl --> Cache[AirQualityRedisCache] Impl -.->|impl| Gw[AirQualityGateway] Cache -.->|impl| CIf[AirQualityMeasurementCache]
테스트 케이스
- 3단계 체인이 순서대로 호출되어 pm10·pm25·측정소·측정시각을 파싱한다
- 캐시 히트 시 외부 API를 0회 호출하고 캐시 값을 반환한다
- getNearbyMsrstnList가 5xx면 AirQualityMeasurement.empty()를 반환한다(예외 전파 없음)
- read 타임아웃 시 empty로 degrade한다
- 동일 그리드키 반복 요청은 TTL 내 캐시로 수렴한다(멱등)