| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- database
- web
- version-control
- 버전관리
- frontend
- Security
- auth
- Debugging
- DevOps
- CI
- SRE
- Kubernetes
- Performance
- Microservices
- Ops
- HTTP
- aws
- backend
- react
- architecture
- Operations
- API
- observability
- CSS
- NextJS
- JavaScript
- Infra
- 성능
- reliability
- Git
- Today
- Total
고민보단 실천을
API 에러 응답 표준화: RFC 9457 Problem Details로 error format 통일하기 본문
API 에러 응답 표준화: RFC 9457 Problem Details로 error format 통일하기
에러 응답이 엔드포인트마다 다르면, 프론트는 화면마다 예외 처리를 다시 씁니다.
RFC 9457(Problem Details)을 기준으로 에러 포맷을 통일하고, 운영에서 디버깅이 쉬워지는 형태로 정리합니다.
이 글의 목표는 '개념 정리'보다, "어떤 기준으로 결정할지"와 "어떻게 운영에서 사고를 줄일지"를 남기는 것입니다.
왜 이게 어려운가(운영 관점)
API/HTTP 영역은 '작은 정책'이 전체 사용자 경험과 운영 비용을 바꿉니다. 그래서 실무에서는 구현보다도 기준(정책)과 검증 루프가 중요합니다.
특히 프록시/CDN/게이트웨이가 있는 환경에서는 서버 코드만 보면 원인을 놓치기 쉽습니다. 레이어를 같이 정리해두면 같은 장애를 반복하지 않게 됩니다.
실전 내용(바로 적용)
에러 응답이 엔드포인트마다 다르면, 프론트는 화면마다 예외 처리를 다시 씁니다.
RFC 9457(Problem Details)을 기준으로 에러 포맷을 통일하고, 운영에서 디버깅이 쉬워지는 형태로 정리합니다.
핵심 요약(결론부터)
- 기준(정책)을 먼저 정하고, 구현/도구는 그 다음에 선택한다
- 실패/예외/회귀를 운영 체크리스트로 막는다
- 공식 문서를 최종 근거로 삼고, 팀 문서로 재가공한다
표준화가 주는 이득
- 프론트/모바일이 공통 에러 핸들러를 만들 수 있다
- 로그/알람에서 error type/code로 집계가 가능해진다
- 문서(OpenAPI)와 테스트가 쉬워진다
Problem Details 핵심 필드
type, title, status, detail, instance가 기본
추가 필드(extensions)로 errorCode/traceId 등을 넣을 수 있다
실무 규칙(추천)
- HTTP status는 프로토콜 의미(401/403/409/429/500)를 유지
- business errorCode는 별도 필드로 관리(문서/버전 관리)
- instance에 request id 또는 디버깅 키를 담아 추적 가능하게
예시 응답(JSON)
{
"type": "https://example.com/problems/order-not-found",
"title": "Order not found",
"status": 404,
"detail": "주문을 찾을 수 없습니다.",
"instance": "/orders/123",
"errorCode": "ORDER_NOT_FOUND",
"traceId": "00-..."
}운영 체크리스트(바로 적용)
- 에러 포맷 1개를 모든 API에 강제(ControllerAdvice/Filter)한다
- errorCode 목록을 문서(OpenAPI/README)로 관리하고 변경 정책을 둔다
- 에러 응답에 traceId/requestId를 포함해 운영 추적성을 올린다
FAQ
Q. 그냥 message만 내려주면 안 되나요?
A. 사용자에게는 message가 중요하지만, 운영/디버깅/자동화에는 구조화된 필드가 필요합니다. 둘을 같이 만족시키는 포맷이 Problem Details입니다.
마무리: 다음 액션
- 팀의 기본값(정책)을 1페이지로 문서화한다
- 대표 시나리오 1개를 코드/설정 예시로 고정한다
- 배포 전후 지표(p95/p99, 오류율)를 비교해 효과를 확인한다
자주 하는 실수(사고 패턴)
- 결정 기준 없이 팀원 취향으로 기술을 고른다
- 문서(스키마)와 구현이 어긋난 상태를 장기간 방치한다
- 재시도/타임아웃을 '늘리기'만 하고 예산/정렬을 안 맞춘다
- 장애 시나리오(429/timeout/partial failure)를 테스트에 넣지 않는다
적용 순서(추천)
- 1) 바꾸려는 것(성능/보안/호환성/운영 단순화)을 한 문장으로 정의한다
- 2) 기본값과 예외를 먼저 정하고, 예외는 만료일/사유/소유자를 남긴다
- 3) 대표 시나리오(요청/응답 예시)를 만들어 계약으로 고정한다
- 4) 지표(p95/p99, 오류율, 재시도율)로 배포 전후를 비교한다
- 5) CI/PR에서 자동 검증(린트/스키마 diff/계약 테스트)을 걸어 회귀를 막는다
검증/회귀 방지
- 배포 전후 지표(p95/p99, 4xx/5xx, 재시도율)를 동일 조건으로 비교
- 프록시/CDN/게이트웨이 설정 변경 이력을 남기고, 롤백 플랜을 준비
- 대표 시나리오를 e2e 테스트로 고정(문서가 아니라 테스트가 계약이 되게)
팀 합의 템플릿(복붙용)
# 팀 합의 템플릿(복붙용)
목표: (예) 구버전 클라이언트 유지하면서 응답 스키마 변경
기본값: (예) /v1 경로 버전 사용
예외: (예) 내부 API는 헤더 버전 허용(게이트웨이 필수)
대표 시나리오: (요청/응답 예시 첨부)
모니터링: (오류율/지연/트래픽) 대시보드 링크
EOL/변경 정책: (날짜/공지 채널/롤백 규칙)FAQ
Q. 그냥 message만 내려주면 안 되나요?
A. 사용자에게는 message가 중요하지만, 운영/디버깅/자동화에는 구조화된 필드가 필요합니다. 둘을 같이 만족시키는 포맷이 Problem Details입니다.
참고/출처
버전/환경에 따라 동작이 달라질 수 있으니, 최종 기준은 공식 문서를 확인합니다.
