HTTP API 에러 처리의 어려움과 RFC7807
(gosuda.org)HTTP API를 개발할 때 에러 처리는 종종 번거로운 부분입니다. API 수가 많아지고 내부 로직이 복잡해질수록 세 가지 측면에서 어려움이 발생합니다.
- 적절한 에러 코드 반환: 경험이 부족한 개발자의 경우 복잡한 로직에서 일관된 HTTP 상태 코드를 사용하기 어렵습니다.
- 많은 양의 결과 로그 작성: 에러 발생 시 예상되는 모든 종료 지점에 로그를 기록하는 것은 코드 양을 늘리고 관리를 복잡하게 합니다.
- 명확한 에러 메시지 전송: 클라이언트에게 단순히 에러 메시지를 전달하는 것만으로는 에러를 명확하게 이해하고 처리하기 어렵습니다.
적절한 에러 코드 반환 개선
에러 코드 사용의 일관성 문제를 해결하기 위해 StatusCode
와 Message
를 포함하는 HttpError
인터페이스 또는 구조체를 구현하는 방법을 제안합니다.
-
해결책:
-
HttpError
타입 정의: HTTP 상태 코드와 메시지를 캡슐화. - 헬퍼 함수 제공:
httperror.BadRequest("wrong format")
와 같이 특정 에러 코드를 반환하는 헬퍼 함수를 사용하여 에러 객체를 쉽게 생성.
-
-
장점:
- IDE의 자동 완성 기능을 활용하여 편리하고 안정적으로 에러 코드와 메시지 입력.
- 수동으로 숫자 코드를 입력하는 것보다 오류 발생 가능성 감소.
- 사전에 준비된 설계 문서를 일일이 확인하는 번거로움 감소.
로그 작성 중앙화
반복적인 로그 작성을 줄이고 에러 처리 로직을 한 곳에서 관리하기 위해 HTTP 핸들러를 래핑하는 방법을 제시합니다.
-
해결책:
-
커스텀 라우터(
chiwrap.Router
) 구현:chi.Router
와 같은 기존 라우터를 내부에 포함하고 에러 처리 로직을 추가합니다. -
핸들러 래핑: 커스텀 라우터의
Get
등의 메서드는HandlerFunc
를 받아서 내부적으로 실행하고, 에러가 발생하면 중앙 처리 로직으로 전달합니다. -
에러 콜백 함수:
NewRouter
생성 시errCallback
함수를 받아 에러 발생 시 해당 콜백을 호출하여 중앙에서 로그를 기록하거나 추가적인 처리를 수행합니다.
-
커스텀 라우터(
-
장점:
- API 로직에서 에러 발생 시 자동으로 적절한 에러 코드와 메시지가 응답으로 반환.
- 서비스별로 적절한 로그를 기록하도록 콜백 함수를 등록하여 로그 관리가 용이.
- 코드 중복을 줄이고 유지보수성 향상.
명확한 에러 메시지 전송 (RFC7807 활용)
클라이언트가 에러를 더 명확하게 이해하고 처리할 수 있도록 RFC7807 표준을 활용한 구조화된 에러 메시지 전송 방안을 제안합니다.
-
RFC7807 주요 요소:
-
type
: 에러 유형을 식별하는 URI (예:https://example.com/errors/validation
). -
title
: 에러에 대한 짧은 한 줄 설명. -
status
: HTTP 상태 코드와 동일. -
detail
: 사람이 읽을 수 있는 상세 에러 설명. -
instance
: 에러가 발생한 특정 URI (예:/api/users/abc
). -
extensions
: 추가 정보를 담는 JSON 객체 (예:invalid_field
,expected_format
).
-
-
구현:
-
RFC7807Error
구조체 생성 및 주요 요소 포함. -
메서드 체이닝 패턴(
WithType()
,WithInstance()
,WithExtension()
)을 통해 쉽게 구조화된 에러 객체 생성. -
ToHttpError()
메서드를 통해RFC7807Error
를HttpError
로 변환하여 중앙화된 라우터와 연동 가능. -
클라이언트가 에러의 종류, 원인, 발생 위치 등을 명확하게 파악 가능.
-
API 응답의 일관성과 유용성을 높여 클라이언트 개발 효율성 증대.
-
좋은 글 감사합니다!
참고로 스프링에서는 spirng-web 라이브러리 > org.springframework.http.ProblemDetail
에 구현체가 존재합니다!
좋은 소개 감사합니다!
찾아보니 RFC 9457로 대체됐네요.
https://datatracker.ietf.org/doc/html/rfc9457
(기존 7807 문서: https://datatracker.ietf.org/doc/html/rfc7807)
RFC 7807과 RFC 9457의 주요 차이점
- 문제 유형 관리: 7807은 커스텀 URI만 사용 가능, 9457은 IANA 공유 레지스트리 도입
- 다중 오류 처리: 7807은 HTTP 207 상태 코드 사용 권장, 9457은 단일 문제 유형 내에서
errors
배열을 사용해 관련 오류를 그룹화 - 확장 필드: 7807은 임의 필드 추가 가능, 9457은 문제 유형별 예상 필드 명시적 연관
- 보안 권고: 7807은 미포함, 9457은 보안 취약점 방지를 위한 명시적 지침 추가
- JSON 포인터: 7807은 미지원, 9457은
pointer
필드 공식 지원
2023년 7월 이후 신규 프로젝트에서는 RFC 9457을 적용하는 것을 권장