← 전체 글로 돌아가기

API

TypeScript 유니온 타입으로 API 성공과 실패 응답을 나눈 비교

status 코드를 여러 곳에서 검사하던 클라이언트 코드를 판별 가능한 유니온으로 바꾼 이유와 트레이드오프입니다

data가 항상 있다고 가정한 코드

프로필 저장이 실패했는데 화면이 이전 이름을 보여주는 버그를 만났습니다. 호출부는 data.name을 바로 읽고 실패 메시지는 전역 변수에서 찾았습니다. data? 타입은 잘못된 조합을 막지 못했습니다.

두 모델 비교

type LooseResult = { ok: boolean; data?: Profile; message?: string };
type Result<T> =
  | { ok: true; data: T }
  | { ok: false; code: string; message: string };
function showResult(result: Result<Profile>) {
  if (result.ok) return renderName(result.data.name);
  showError(`${result.code}: ${result.message}`);
}

선택적 필드는 작성하기 쉽지만 성공인데 data가 없는 조합을 허용합니다. ok를 판별자로 둔 유니온은 분기 안에서 필요한 값이 자동으로 좁혀집니다. 서버 snake_case 변환도 API 경계에서 한 번만 처리했습니다.

기준선택적 필드판별 유니온
초기 작성량적음조금 많음
잘못된 조합 방지약함강함
오류별 UI 분기복잡해짐명확함

언제 과한가

단순 조회이고 라이브러리가 이미 예외를 던진다면 유니온이 타입만 늘릴 수 있습니다. 반대로 폼에서 검증, 권한, 중복 오류를 다르게 보여줘야 한다면 code가 있는 유니온이 유리합니다.

적용 후 확인한 것

  • 실패 응답에서 data를 읽는 코드가 막히는가
  • 네트워크 오류와 업무 오류를 구분했는가
  • API 경계에서 실제 JSON을 검증하는가

타입 변경이 API를 고치지는 않지만 호출부의 가정을 코드에 남겨 줍니다. 상태가 두 종류 이상인 응답에는 판별 유니온을 먼저 검토합니다.