스프링 프로젝트 하면 ResponseEntity 나 Custom 응답을 만들어서 프런트엔드와 소통한다. 거기에 꼭 포함되는 게 HTTP Status Code이다.
자주 사용하는 200, 201, 400, 401은 알지만 나머지는 그냥 안 쓰는 코드네 이걸로 사용해야지 하고 사용했던 경험이 있다. 이참에 HTTP 상태코드를 정리해 보자.
HTTP Status Code(HTTP 상태코드)
HTTP 상태코드는 3자리 숫자로 만들어지며, 첫 번째 자리는 1에서 5까지 제공한다. 첫 번째 자리가 4와 5인 경우는 정상적인 상황이 아니라고 판단되므로 관리자나 개발자가 확인하여 처리해줘야 한다.
- 1xx(정보) : 요청을 받았으며 프로세스를 계속 진행한다.
- 2xx(성공) : 요청 정상 처리되었다.
- 3xx(리다이렉션) : 요청 완료를 위해 추가 작업 조치가 필요하다.
- 4xx(클라이언트 오류) : 클라이언트의 오류, 잘못된 문법등으로 서버가 요청을 처리할 수 없다.
- 5xx(서버 오류) : 서버 오류, 서버가 정상 요청을 처리하지 못한다.
1xx 정보
서버가 요청을 잘 받았으며 해당 프로세스를 계속 이어가며 처리하는 것을 의미한다.
사실 거의 사용되지 않으므로 100번 정도만 알고 넘어가자.
- 100(Continue) : 계속함을 의미(진행 중임을 의미하는 응답코드), 현재까지의 진행상태가 문제없으며, 클라이언트가 계속해서 요청을 하거나 이미 요청을 완료한 경우에는 무시해도 되는 것을 알려준다.
2xx 정보
클라이언트의 요청을 성공적으로 처리함을 의미한다.
가장 많이 사용되는 상태코드이다.
- 200(OK) : 요청이 성공적으로 되었고, 정보는 요청에 따른 응답으로 반환된다. (GET members/10 같은 요청을 생각하자.)
- 201(Created) : 요청이 성공적이었으며, 그 결과로 새로운 리소스가 생성되었다. 주로 POST 요청이나 일부 PUT 요청에 활용된다.
- 202(Accepted) : 요청이 접수는 되었으나 처리가 완료되지 않았다. 배치 처리 같은 곳에서 사용된다. (요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리한다.)
- 204(No Content) : 서버의 요청을 성공적으로 수행하였지만, 응답 페이로드 본문에 보낼 데이터가 없을 때 사용한다.
예를 들면 웹 문서 편집기 save 버튼같은 것을 생각하면 된다. 웹 문서 편집기는 save 버튼의 결과로 아무 데이터를 보내주지 않아도 된다. 즉 눌러도 같은 화면을 유지하는 경우 주로 사용된다.
개발팀에 따라 성공코드를 200으로 고정하거나 200, 201만 활용하자라고 정해두니 가이드에 맞춰 사용하면 된다.
3xx 정보
요청을 완료하기 위해 유저 에이전트의 추가 조치 필요하다. 3xx 대 상태코드는 응답의 결과로 Location 헤더를 같이 반환한다. 해당 헤더가 있으면 Location 위치로 자동이동하며, 이것을 리다이렉트 한다고 한다.
리다이렉션의 이해
자동 리다이렉션의 흐름을 이해해보자.
기존 이벤트(/event)가 진행되었고 마무리되었다. 그 후 새로운 이벤트(new-event)가 진행 중인데 클라이언트가 기존 이벤트로 접속 시에 대한 처리 로직이다.
기존 이벤트페이지 접근할 경우 서버는 301 상태코드와 Location 헤더값을 같이 전송한다. 클라이언트는 해당 응답값에 따라 자동 리다이렉션을 실행하며 새로운 이벤트 페이지로 다시 접근한다. (사용자 관점에서는 매우 빠르게 이루어지기 때문에 인식되지는 않는다.)
리다이렉션의 종류
- 영구 리다이렉션 - 특정 리소스의 URI가 영구적으로 이동한다.
- 예 ) /members -> /users(유저에 대한 경로가 변경됨), /event -> /new-event(기존 이벤트가 종료되고 새로운 이벤트가 진행 중)
- 일시 리다이렉션 - 일시적인 변경
- 주문 완료 후 주문 내역 화면으로 이동
- PRG: Post/Redirect/Get
- 특수 리다이렉션
- 결과 대신 캐시를 사용한다.
영구 리다이렉션(301, 308)
리소스의 URI이 영구적으로 이동됨을 의미하며, 원래의 URL를 사용하지 않으며 검색 엔징 등에서도 변경을 인지한다.
- 301(Moved Permanently) : 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있다.
- 308(Permanently Redirec) : 301과 기본적으로 기능은 같다. 하지만 리다이렉트시 요청 메서드와 본문을 유지한다.
대부분 실무에서는 새로운 페이지로 변환하면 필요한 본문 내용도 달라지기 때문에 308보단 301로 보내 GET으로 처리한다. (사실 둘 다 그렇게 활용되지 않는다고 한다. 뒤에서 나오는 일시적인 리다이렉션을 주로 사용한다.)
일시적인 리다이렉션(302, 307, 303)
리소스의 URI가 일시적으로 변경된다. 따라서 검색엔진 등에서 URL을 변경하면 안 된다.
- 302(Found) : 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있다.
- 307(Temporary Redirect) : 302와 기능은 같다. 리다이렉트시 요청 메서드와 본문을 유지한다.(요청 메서드를 변경하면 안된다.)
- 303(See Other) : 302와 기능은 같다. 리다이렉트시 요청 메서드가 GET으로 변경한다. (302가 대부분 GET으로 변하지만 브라우저에 따라 안 되는 경우가 있다.)
하지만 실무에서는 303, 307처럼 명확한 코드를 사용하길 윈 하지만 현실적으로 302를 기본적으로 많이 사용한다. GET으로 변하면 안 되는 경우만 따로 307로 빼서 사용하면 된다.
일시적인 리다이렉션은 언제 사용될까? (PRG: Post/Rediect/Get)
POST로 주문 후에 웹 브라우저를 새로고침 한다면 어떻게 될까? 새로고침은 마지막 요청에 대해 다시 요청을 한다는 의미이며 그렇기 때문에 중복 주문이 발생될 수 있다. (요즘에는 브라우저에서 경고창을 띄어준다고 한다. 다시 제출하시겠습니까?)
새로고침을 통한 중복 요청을 방지하기 위해 PRG가 사용된다.
- POST 요청 처리 후 결과 화면에서 GET 메서드로 리다이렉트 시킨다.
- 새 로고침해도 결과 화면을 GET으로 조회한다. (새로고침은 마지막 요청을 다시 요청하니깐)
- 중복 주문 대신 결과 화면만 GET으로 다시 요청된다.
PRG은 클라이언트에서의 중복을 막는데 많이 사용된다. 클라이언트단에서 PRG 막았다 하더라도 POST 중복요청은 들어올 수 있으니 서버 쪽에서도 중복을 막는 처리를 동시에 진행하여야 한다. (주문코드 등 유니크한 설정을 추가하여)
기타 리다이렉션(300, 304)
- 300(Multiple Choices) : 안 쓴다.
- 304(Not Modified) : 자주 사용된다. 캐시를 목적으로 사용하며 클라이언트에게 리소스가 수정되지 않았음을 알려준다. 따라서 클라이언트는 로컬 PC에 저장된 캐시를 재사용한다.
304 응답은 응답에 메시지 바디를 포함하면 안 된다. (로컬 캐시를 사용해야 하므로)
조건부 GET, HEAD 요청 시 사용
304는 실무에서 많이 사용된다고 하는데 나는 사용해 본 적이 없어 예제등을 찾아서 공부를 추가적으로 진행하여야 될 것 같다.
4xx 정보
클라이언트 오류
- 클라이언트의 요청에 잘못된 문법등으로 서버가 요청을 수행할 수 없다.
- 오류의 원인이 클라이언트에 있다.
- 클라이언트에서 잘못된 요청(잘못된 데이터)을 보내는 것이므로, 똑같이 재시도하여도 오류가 발생한다.
400(Bad Request)
클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없다.
- 요청 구문, 메시지 등 오류
- 클라이언트는 요청 내용을 다시 검토하여 보내야 한다.
- 예 ) 요청 파라미터가 잘못되거나, API 스펙이 맞지 않을 경우
401(Unauthorized)
클라이언트가 해당 리소스에 대한 인증이 필요하다.
- 인증(Authentication)되지 않았다.
- 401 오류 발생 시 응답에 WWW-Authenticate 헤더와 함께 인증 방법을 설명한다.
- 참고
- 인증(Authentication) : 본인이 누구인지 확인(로그인)
- 인가(Authorization) : 권한부여 (ADMIN 권한처럼 특정 리소스에 접근할 수 있는 권한, 인증이 있어야 인가가 있다.)
- 오류 메시지가 Unauthorized이면 인가에 대한 처리인 거 같지만 인증에 대한 처리를 한다. (이름이 아쉽다.)
403(Forbidden)
서버가 요청을 이해했지만 승인을 거부한다.
- 주로 인증 자격 증명은 있지만, 접근 권한이 불충분한 경우 사용된다.
- 예 ) 어드민 등급이 아닌 사용자가 로그인은 했지만, 어드민 등급의 리소스를 접근하는 경우 발생된다.
404(Not Found)
요청 리소스를 찾을 수 없다.
- 요청 리소스가 서버에 없다.
- 또는 권한이 부족한 리소스에 접근할 때 리소스를 숨기고 싶을 때 사용된다. (비권한 사용자가 접근 시 이 페이지가 있다는 사실을 숨기고 싶을 때)
5xx 정보
서버오류
- 서버 문제로 오류 발생
- 서버에 문제가 있기 때문에 재시도하면 성공할 수 도 있음(서버나 DB가 복구되거나 등)
500(Internal Server Error)
서버 내부 문제로 오류 발생, 애매하면 500 오류를 사용한다.
503(Service Unavailable)
서비스 이용 불가
- 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없다.
- Retry-After 헤더 필드로 얼마뒤에 복구되는지 보낼 수도 있다.
대부분의 서비스 이용 불가 장애는 예측할 수 없으므로 500으로 처리되는 게 일반적이다.
참조
https://www.whatap.io/ko/blog/40/
인프런 강의 [CS지식의 정석]
인프런 강의 [모든 개발자를 위한 HTTP 웹 기본 지식]
'Knowledge > 네트워크' 카테고리의 다른 글
[네트워크] 범위에 따른 네트워크 분류 (0) | 2024.05.10 |
---|---|
[네트워크] 네트워크와 인터넷, 네트워크의 기본구조 (0) | 2024.05.09 |
[네크워크] CORS란? (+ Spring Boot에서 설정하기) (0) | 2023.12.12 |
[네트워크] 세션(Session) vs 쿠키(Cookie) vs 토큰(Token) (0) | 2023.12.07 |
[스친초5기/네트워크] HTTP와 HTTP 메서드 (0) | 2023.11.07 |