- 요청이 수신되었고 처리가 계속되고 있음을 나타냄
- 핵심은 '연결 상태 확인'
- 브라우저나 HTTP 클라이언트가 자동 처리하므로 개발 과정에서 직접 다룰 일을 적음
- 대표적으로 WebSocket 연결 시작시 볼 수 있는 101 Switching Protocols 등이 있음
200 : GET 요청 성공, PUT/PATCH 업데이트 완료됨 등
201 Created : POST요청으로 인한 새 리소스 생성시 반환, 주로 Location 헤더에서 새로 생성된 리소스 URI를 같이 보냄 (회원가입, 게시글 등)
204 No Content : 요청은 성공했으나 응답 본문이 없는 경우. DELETE 요청 성공시나, 좋아요 버튼 등 별도의 응답 데이터가 필요 없는 경우 사용
301 Moved Permanetly : 영구적인 URL 변경일 때 사용. 브라우저는 새로운 주소를 캐싱해서 다음부터는 바로 새 주소로 이동
302 Found : 임시 리다이렉션
- '로그인 후 원래 페이지로 돌아가기'같은 일시적인 이동에 사용
- 최근엔 303 See Other 혹은 307 Temporary Redirect가 의미상 더 명확하므로 이쪽을 사용하는 것을 권장
304 Not Modified : 캐시 관련 코드
- 클라이언트가 가진 캐시가 유효할 때 서버가 이를 반환하여 불필요한 데이터 전송을 줄임
400 Bad Request : 요청 형식이 잘못됨
- JSON 파싱 실패, 필수 파라미터 누락 등
- SpringBoot에서는 @Valid로 검증 실패시 기본적으로 해당 400 오류코드 반환
401 Unauthorized : 인증되지 않음
- 로그인 필요한 곳에 접근했거나
- 토큰이 만료된 경우 등
- Spring Security에서 자주 보게 됨
403 Forbidden : 인증은 됐지만 권한이 없는 경우
- 일반 사용자가 어드민 페이지에 접근하려는 경우 등
404 Not Found : 리소스가 존재하지 않을 때
- 서버에 존재하지 않는 API 엔드포인트
- 존재하는 엔드포인트지만 리소스가 없을 때 (DB 조회 결과 없음)
- 핵심은 '요청한 것을 찾을 수 없다'는 포괄적 의미
405 Method Not Allowed : 지원하지 않는 HTTP 메서드
- GET만 허용하는 엔드포인트에 POST 요청시 발생 등..
409 Conflict : 요청이 현재 서버 상태와 충돌할 때
- 동시성 문제 , 중복 데이터 생성시의 경우 발생
- ex) 이미 존재하는 이메일로 회원가입 시도시
422 Unprocessable Entity
- 요청 형식은 맞지만 비즈니스 로직상 처리할 수 없는 경우
- 400과 유사하지만 조금 더 구체적임
429 Too Many Requests : Rate limiting 걸림
- API 호출 횟수 제한 초과 시 발생 등
500 Internal Server Error : 서버측의 예상치 못한 에러
- NullPointerException 등 처리되지 않은 예외 발생시 기본적으로 나옴
- 프로덕션에서는 적절한 에러 핸들링을 통해 구체적인 4xx 코드를 반환하는 것이 좋음
502 Bad Gateway : 게이트웨이나 프록시가 upstream 서버로부터 잘못된 응답을 받은 경우
- ex)Nginx 뒤에 SpringBoot 앱이 있는 구조에서, SpringBoot 앱이 다운되거나 응답이 없으면 Nginx 측에서 반환
503 Service Unavailable : 서버가 일시적으로 요청 처리 불가
- 서버 점검 중
- 서버 과부하 상태
504 Gateway Timeout : 게이트웨이가 upstream 서버 응답을 기다리가 타임아웃됨
- ex)DB 쿼리가 너무 오래 걸려서 응답이 오지 않으면 발생 등
- 클라이언트 - 서버간의 공통 언어
표준이 없을 시, 각 API마다 고유의 규칙을 제정해야 함
{ status: "success" } // A 회사
{ result: "ok" } // B 회사
{ code: 1000 } // C 회사
// 어떤 API든 동일하게 처리 가능
axios.get('/api/users')
.then(response => {
// 2xx면 성공
})
.catch(error => {
if (error.response.status === 401) {
// 어떤 API든 401은 로그인 필요
redirectToLogin();
} else if (error.response.status === 404) {
// 어떤 API든 404는 없는 리소스
showNotFound();
}
});
- 브라우저와 HTTP 클라이언트의 자동 처리
- 브라우저와 HTTP 클라이언트는 이미 상태코드를 이해하고 있고, 적절하게 처리하고 있음
- 301/302 : 브라우저가 자동으로 리다이렉트
- 304: 브라우저가 캐시된 데이터 사용
- 401: Axios 같은 라이브러리가 자동으로 인터셉터에서 잡아서 토큰 갱신
- 5xx: 재시도 로직 자동 실행
- 만일 모든 응답을 200으로 보내고 body에서 성공/실패를 구분한다면 이런 자동화 기능을 사용하지 못함
- 인프라 레벨에서의 활용
- Nginx, 로드 밸런서, API Gateway 등의 미들웨어들도 상태 코드를 참조함
- CloudWatch, DataDog 등의 모니터링 도구도 상태 코드로 메트릭을 수집함
- "4XX 에러율이 증가했다 -> 클라이언트 문제 (Front-End 배포 오류 가능성)
- "5XX 에러율이 증가했다 -> 서버 문제 (DB 다운 혹은 메모리 부족 등)
# Nginx 설정 예시
if ($status = 502) {
# 502면 다른 upstream 서버로 재시도
}
# 5xx 에러가 많으면 헬스체크 실패로 판단
- 디버깅과 로깅
- 개발자 도구 Network 탭에서 응답 상황 체크 가능
- 상태 코드별로 필터링 조회 가능
- REST API 설계 철학
- RESTful API는 HTTP프로토콜의 기능을 최대한 활용하는 것을 목표로 함
- HTTP 메서드 (GET, POST, PUT, DELETE)
- HTTP 헤더 (Content-Type, Authrization)
- HTTP 상태 코드
- 프로토콜의 명세 기능을 잘 사용하면, 응답 본문 없이 헤더만으로 어떤 일이 일어났는지 파악 가능