이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • Fallback과 Degradation은 가짜 성공과 어떻게 다른가?
  • 어떤 데이터는 stale fallback이 가능하고, 어떤 데이터는 실패를 명확히 반환해야 하는가?
  • 축소 응답이 성능, 정합성, 장애 격리, 운영 복잡도를 어떻게 바꾸는가?

개요

Fallback은 실패를 숨겨 성공처럼 보이게 만드는 기술이 아니다. 핵심 기능을 살리기 위해 부가 기능을 축소하고, 그 상태를 사용자와 운영자가 이해할 수 있게 드러내는 API 계약이다.

배송 위치를 못 가져올 때 주문 상세 전체를 500으로 만드는 것은 과하다. 하지만 배송 상태를 “배송 완료”처럼 꾸며서 반환하면 더 위험하다. 올바른 fallback은 “주문은 정상이고 배송 추적만 잠시 불가”를 표현한다.

Fallback의 종류

종류예시주의점
캐시 fallback최근 배송 위치 표시데이터가 오래되었음을 표시
부분 응답주문 정보만 반환누락된 필드를 명확히 표현
기본값추천 상품 빈 목록기본값이 잘못된 판단을 만들지 않아야 함
기능 숨김추천 영역 제거UX가 급격히 깨지지 않아야 함
pending후속 처리 중 표시상태 조회 경로 필요
명확한 실패결제 승인 실패재시도와 idempotency 필요

Fallback 선택은 데이터의 정합성 위험과 사용자 행동에 따라 달라진다.

적용하면 안 되는 곳

모든 실패에 fallback을 넣으면 위험하다.

Fallback이 부적합한 경우:

  • 결제 승인 결과를 모르는 상태에서 성공처럼 보여준다.
  • 재고 차감 실패를 숨기고 주문 성공을 반환한다.
  • 권한 확인 실패 시 기본 허용으로 처리한다.
  • 신원 인증 실패를 캐시된 성공으로 대체한다.

이 경우에는 빠른 실패와 명확한 재시도 계약이 낫다. 장애 격리는 정합성을 속여도 된다는 뜻이 아니다.

배송 조회 응답 예시

{
  "orderId": "ord-1001",
  "orderStatus": "PAID",
  "shipping": {
    "status": "TEMPORARILY_UNAVAILABLE",
    "message": "배송 추적 정보를 잠시 불러올 수 없습니다.",
    "source": "fallback",
    "lastKnownAt": "2026-07-01T09:30:00+09:00"
  }
}

이 응답은 주문 상태와 배송 추적 상태를 분리한다. 사용자는 주문이 실패한 것이 아니라 배송 추적 정보만 축소되었다고 이해할 수 있다.

Degradation 단계

Degradation은 단계적으로 설계한다.

Level 0: 정상 응답
Level 1: 느린 부가 정보 제거
Level 2: 캐시된 부가 정보만 표시
Level 3: 핵심 정보만 표시
Level 4: 쓰기 차단, 읽기만 허용

장애 중 어떤 단계로 갈지 미리 정해야 한다. 즉흥적으로 기능을 끄면 사용자 안내, 고객센터, 운영 지표가 따라오지 못한다.

성능과 정합성

Fallback은 성능을 보호하지만 정합성 표현을 바꾼다.

  • 캐시 fallback은 빠르지만 stale data를 보여줄 수 있다.
  • 기본값 fallback은 빠르지만 사용자가 기능이 없다고 오해할 수 있다.
  • 부분 응답은 핵심 경로를 살리지만 클라이언트가 null과 unavailable을 구분해야 한다.
  • 명확한 실패는 정합성은 지키지만 사용자 성공률이 낮아질 수 있다.

따라서 fallback 필드에는 데이터 출처와 최신성 정보가 필요할 수 있다.

클라이언트 계약

클라이언트는 fallback 상태를 정상 데이터와 구분해야 한다.

{
  "field": "shipping",
  "status": "DEGRADED",
  "retryable": true,
  "retryAfterSeconds": 60
}

모바일 앱은 이 정보를 보고 배송 영역만 재조회할 수 있다. 웹은 배송 영역에만 안내 문구를 띄울 수 있다.

운영 지표

Fallback은 성공률 통계에서 분리해야 한다.

HTTP 200 success = 98%
fallback response = 22%
shipping provider error = 35%
user complaint = 증가

HTTP 200만 보면 정상처럼 보인다. fallback rate가 높으면 사용자는 축소된 서비스를 쓰고 있는 것이다.

Fallback Source

Fallback의 출처를 구분한다.

source의미
cache최근 성공 값을 사용
default안전한 기본값 사용
hidden기능 영역 숨김
unavailable대체 불가, 명확한 실패

운영자는 source별 비율을 보고 어떤 fallback이 자주 쓰이는지 알아야 한다.

위험 신호

  • fallback 응답이 정상 응답과 구분되지 않는다.
  • 결제, 재고, 권한 같은 강한 정합성 경로에 캐시 fallback을 쓴다.
  • HTTP 200 비율만 보고 fallback rate를 보지 않는다.
  • 클라이언트가 degraded 상태를 렌더링할 수 없다.
  • fallback이 오래된 데이터를 무기한 반환한다.
  • 장애가 복구되어도 fallback cache가 계속 남는다.

개인 프로젝트 기준

  • fallback 가능한 필드와 불가능한 필드를 표로 나눈다.
  • fallback 응답에 sourcedegraded를 넣는다.
  • 캐시 fallback을 쓰면 lastUpdatedAt을 표시한다.
  • fallback rate를 로그로 남긴다.

기업 운영 기준

  • degradation level과 전환 조건을 runbook에 둔다.
  • 고객센터와 status page가 같은 축소 상태를 설명할 수 있게 한다.
  • fallback rate, stale age, user impact를 SLO와 연결한다.
  • 기능 축소 상태에서 매출, 주문, support ticket 변화를 본다.

확인 질문

확인 질문

  • 확인 질문: Fallback이 가짜 성공이 되지 않으려면 무엇을 드러내야 하는가?
    • 답변: 어떤 데이터가 축소되었고, 출처가 무엇이며, 얼마나 오래된 값인지 또는 재시도가 가능한지 드러내야 한다.
  • 확인 질문: 결제 승인에 캐시 fallback을 쓰면 안 되는 이유는 무엇인가?
    • 답변: 사용자가 금전 상태를 잘못 믿게 되어 중복 결제나 잘못된 주문 상태 같은 정합성 문제가 생길 수 있기 때문이다.
  • 확인 질문: HTTP 200 성공률과 fallback rate를 분리해야 하는 이유는 무엇인가?
    • 답변: 200 응답이어도 사용자는 축소된 기능을 보고 있을 수 있으므로 실제 사용자 영향이 숨겨지기 때문이다.

참고 문서