API를 설계하다 보면 HTTP 상태 코드와 에러 코드를 혼용하거나, 명확하게 구분하지 않고 사용하는 경우가 종종 있습니다.
하지만 이 둘은 역할과 목적이 다르며, 잘 설계하면 디버깅과 유지보수 효율이 크게 올라갑니다.
이번 글에서는 두 개념의 차이점과 효과적인 설계 방법을 정리해 보겠습니다.
정의
HTTP 프로토콜 표준(RFC 9110 등)에 따라 서버가 요청을 처리한 결과를 숫자로 표현한 값입니다.
범위와 의미
1xx (Informational): 요청 수신 및 처리 진행 중
2xx (Success): 요청이 정상적으로 처리됨
200 OK
, 201 Created
3xx (Redirection): 요청을 다른 위치로 보내야 함
301 Moved Permanently
, 302 Found
4xx (Client Error): 클라이언트 요청이 잘못됨
400 Bad Request
, 404 Not Found
, 409 Conflict
5xx (Server Error): 서버 내부 오류 발생
500 Internal Server Error
, 503 Service Unavailable
특징
정의
애플리케이션이나 서비스 내부에서 발생한 특정 오류 상황을 식별하기 위해 개발자가 정의한 고유 코드입니다.
특징
예시
HTTP 상태 코드 | 에러 코드 | 의미 |
---|---|---|
400 Bad Request | 201 | 필수 필드 누락 (name 값 없음) |
400 Bad Request | 202 | 데이터 형식 불일치 (date 필드가 문자열이 아님) |
401 Unauthorized | 101 | 인증 토큰 만료 |
401 Unauthorized | 102 | 잘못된 API 키 |
403 Forbidden | 301 | 해당 리소스에 접근 권한 없음 |
404 Not Found | 401 | 요청한 리소스가 존재하지 않음 |
409 Conflict | 342 | 이미 동일한 사용자명이 존재 |
500 Internal Server Error | 501 | DB 연결 실패 |
500 Internal Server Error | 502 | 외부 API 호출 실패 |
구분 | 상태 코드 (HTTP) | 에러 코드 (App/System) |
---|---|---|
정의 | HTTP 요청 처리 결과를 표준 숫자로 표현 | 내부 로직/비즈니스 규칙 기반의 고유 오류 식별자 |
표준 여부 | 있음 (RFC 표준) | 없음 (서비스별 정의) |
범위 | 100~599 | 자유롭게 설정 |
목적 | 결과의 큰 범주 전달 | 원인에 대한 세부 식별 |
예시 | 200 OK , 404 Not Found | 344 시작점 오류 , 341 중복 데이터 |
{
"status": 409, // HTTP 상태 코드: 리소스 충돌
"error_code": 341, // 에러 코드: 중복된 데이터 존재
"message": "이미 저장된 데이터가 있습니다."
}
status
(409)는 "무언가 충돌이 있다"는 대분류를 나타내고,error_code
(341)는 구체적으로 "중복 데이터" 문제임을 알려줍니다.HTTP 상태 코드와 에러 코드를 구분해 잘 설계하면 클라이언트-서버 간 의사소통이 명확해지고, 유지보수가 쉬워집니다.
200 OK
로 반환하고, 본문에서만 실패 표시숫자 범위 또는 문자열 패턴을 미리 정해 관리
예:
1xx
: 인증/권한 관련 에러2xx
: 요청 데이터 검증 실패3xx
: 리소스 상태 관련 에러에러 코드와 메시지를 매핑 테이블로 관리 → 코드 변경 시 메시지 자동 반영
{
"status": <HTTP_STATUS_CODE>,
"error_code": <INTERNAL_ERROR_CODE>,
"message": "<DESCRIPTION>",
"data": { ... }
}
error_code
는 기계 친화적 (정수/식별자)message
는 사람이 읽기 쉬운 문장status
, error_code
, 요청 ID, 사용자 정보, 발생 시각을 함께 저장