HTTP Status
in Etc on Etc
- HTTP 상태 코드 (HTTP Status Codes) 정리
HTTP 상태 코드 (HTTP Status Codes) 정리
클라이언트가 보낸 요청의 처리 상태를 응답(Response)에서 알려주는 기능이다.
1. 상태 코드 분류
- 1xx (Informational): 요청이 수신되어 처리 중 (거의 사용하지 않음)
- 2xx (Successful): 요청 정상 처리
- 3xx (Redirection): 요청을 완료하려면 추가 행동이 필요
- 4xx (Client Error): 클라이언트 오류, 잘못된 문법 등으로 서버가 요청을 수행할 수 없음
- 5xx (Server Error): 서버 오류, 서버가 정상 요청을 처리하지 못함
참고: 모르는 상태 코드가 나타날 경우
- 클라이언트는 상위 상태 코드로 해석해서 처리한다. (예: 299 -> 2xx 성공으로 처리)
- 미래에 새로운 상태 코드가 추가되어도 클라이언트를 변경하지 않아도 된다.
2. 2xx (Successful) - 성공
클라이언트의 요청을 성공적으로 처리함
- 200 OK: 요청 성공
- 201 Created: 요청 성공 및 새로운 리소스 생성 (생성된 리소스는 응답의
Location헤더 필드로 식별) - 202 Accepted: 요청이 접수되었으나 처리가 완료되지 않음 (예: 배치 처리)
- 204 No Content: 서버가 요청을 성공적으로 수행했지만, 응답 본문(Payload)에 보낼 데이터가 없음 (예: 웹 문서 편집기의 저장 버튼)
3. 3xx (Redirection) - 리다이렉션
요청을 완료하기 위해 유저 에이전트(웹 브라우저 등)의 추가 조치가 필요함 웹 브라우저는 3xx 응답 결과에 Location 헤더가 있으면 해당 위치로 자동 이동(리다이렉트)한다.
3.1. 영구 리다이렉션 (Permanent Redirection)
특정 리소스의 URI가 영구적으로 이동함 (검색 엔진 등에서도 변경을 인지)
- 301 Moved Permanently: 리다이렉트 시 요청 메서드가
GET으로 변하고, 본문이 제거될 수 있음 (MAY) - 308 Permanent Redirect: 301과 기능은 같으나, 리다이렉트 시 요청 메서드와 본문을 유지함 (처음
POST를 보내면 리다이렉트도POST유지)
3.2. 일시적인 리다이렉션 (Temporary Redirection)
리소스의 URI가 일시적으로 변경됨 (검색 엔진 등에서 URL을 변경하면 안 됨)
- 302 Found: 리다이렉트 시 요청 메서드가
GET으로 변하고, 본문이 제거될 수 있음 (MAY). 대부분의 라이브러리가 기본값으로 사용함. - 307 Temporary Redirect: 302와 기능은 같으나, 리다이렉트 시 요청 메서드와 본문을 유지해야 함 (MUST NOT change method)
- 303 See Other: 302와 기능은 같으나, 리다이렉트 시 요청 메서드가 명확히
GET으로 변경됨
3.3. 기타 리다이렉션
- 304 Not Modified: 캐시를 목적으로 사용. 클라이언트에게 리소스가 수정되지 않았음을 알려주어 로컬 PC의 캐시를 재사용하게 함. (응답에 메시지 바디를 포함하면 안 됨)
4. 4xx (Client Error) - 클라이언트 오류
클라이언트의 요청에 잘못된 문법 등으로 서버가 요청을 수행할 수 없음 중요: 오류의 원인이 클라이언트에 있으므로, 똑같이 재시도하면 계속 실패함
- 400 Bad Request: 클라이언트가 잘못된 요청을 하여 서버가 처리할 수 없음 (요청 구문, 메시지 오류 등)
- 401 Unauthorized: 해당 리소스에 대한 인증(Authentication)이 필요함. (로그인 필요)
- 참고: 이름은 Unauthorized(인가 미비)이지만 실제 의미는 Authentication(인증 미비)임
- 403 Forbidden: 서버가 요청을 이해했지만 승인을 거부함. 인증 자격은 있지만 접근 권한(Authorization)이 불충분한 경우 (예: 일반 사용자가 어드민 리소스 접근)
- 404 Not Found: 요청 리소스가 서버에 없거나, 권한이 부족한 리소스를 숨기고 싶을 때 사용
5. 5xx (Server Error) - 서버 오류
서버 문제로 오류 발생. 서버에 문제가 있기 때문에 재시도 시 성공할 수도 있음
- 500 Internal Server Error: 서버 내부 문제로 오류 발생 (애매하면 500 사용)
- 503 Service Unavailable: 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음 (
Retry-After헤더로 복구 예정 시간 전달 가능)
6. 상황별 선택 가이드 및 실무 활용 (Best Practices)
6.1. 리다이렉션(3xx)은 무엇을 써야 하는가?
과거의 모호함으로 인해 선택이 혼란스러울 수 있으나, 다음과 같은 기준을 권장한다.
- 가장 명확한 선택 (권장):
307또는303302의 모호함(메서드가 GET으로 변하는 현상)을 해결하기 위해 등장한 표준이다.- 307: 리다이렉트 시 요청 메서드와 본문을 그대로 유지해야 할 때 사용한다.
- 303: 리다이렉트 시 요청 메서드를 무조건 GET으로 변경해야 할 때 사용한다.
- 현실적인 선택 (실무):
302- 이미 많은 애플리케이션과 라이브러리가
302를 기본값으로 사용하고 있다. - 자동 리다이렉션 시 메서드가 GET으로 변해도 상관없는 경우라면,
302를 사용해도 큰 문제는 없다.
- 이미 많은 애플리케이션과 라이브러리가
6.2. 중복 주문 방지: PRG (Post/Redirect/Get) 패턴
POST 요청 후 새로고침으로 인한 중복 주문(결제) 사고를 방지하기 위해 필수적으로 사용한다.
- 문제 상황: 클라이언트가 상품 주문(POST)을 완료한 후, 새로고침을 하면 주문이 중복으로 전송될 위험이 있다.
- 해결 방안 (PRG):
- 서버는 주문 처리(POST) 후
200 OK대신302 Found(또는303) 응답을 보낸다. Location헤더에 ‘주문 결과 화면’ URL을 담아 리다이렉트시킨다.- 브라우저는 결과 화면을
GET방식으로 새로 요청하게 된다. - 이후 사용자가 새로고침을 해도 ‘결과 화면 조회(GET)’만 반복되므로 안전하다.
- 서버는 주문 처리(POST) 후
6.3. 성공 응답(2xx)의 디테일한 활용
단순히 200 OK만 사용하는 것보다 상황에 맞춰 구분하면 클라이언트가 처리하기 더 용이하다.
- 데이터 생성이 일어난 경우 (
201 Created): 회원 가입, 게시글 작성 등 리소스가 새로 생성되었을 때 사용한다.Location헤더에 생성된 리소스의 URI를 포함해주면 좋다. - 응답 본문이 필요 없는 경우 (
204 No Content): 웹 에디터의 ‘자동 저장’ 기능처럼, 요청은 성공했으나 사용자에게 보여줄 새 데이터나 화면 전환이 필요 없을 때 최적이다.
6.4. 에러 처리 (4xx vs 5xx)의 책임 구분
에러의 책임을 명확히 구분하는 것이 디버깅과 운영에 중요하다.
- 클라이언트 잘못 (
4xx): 요청 파라미터 오류, 로그인 필요 등. 이 경우 클라이언트가 수정 없이 재시도하면 계속 실패해야 한다. - 서버 잘못 (
5xx): DB 접속 실패, NullPointerException 등. 이 경우는 재시도 시 성공할 가능성이 있다. - Tip: 로직상 예외가 발생했을 때 애매하면 무조건
500을 던지기보다, 원인이 클라이언트에게 있다면 확실하게4xx로 변환해서 던져주는 것이 좋다.