클라이언트가 서버로 요청을 보내면 해당 요청이 잘 처리가 되었는지, 문제가 있는지 http 응답 메시지가 올때 알려주는 기능이다
Q. 클라이언트가 인식할 수 없는 상태코드를 서버가 반환한다면?
A. 클라이언트는 상위 상태코드로 해석해서 처리하면 된다
거의 사용되지 않는다
200 OK
201 Created
(리소스 생성, POST로 등록 등의 경우)202 Accepted
203 No Content
클라에서 보낸 요청이 성공했다
GET /members/100 을 조회 요청 -> 클라 응답으로 정보 반환 & 200 OK
요청 성공해서 새로운 리소스가 생성 되었다
POST /members + html body 로 등록 요청 -> 클라 응답으로 해당 리소스 URI 설정해서 등록하고 & 201 Created
html 응답 헤더에 Location을 추가해서 반환 (생성된 리소스 URI)
요청이 접수는 되었지만 처리는 완료되지 않았다
서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없는 경우
꼭 많은 종류의 상태 코드를 사용한다고 좋은것이 아니다. 200번과 201번만 사용하는 등 팀간의 약속을 통해서 맞춰서 사용하는 것이 좋다
요청을 완료하기 위해 유저 에이전트(클라이언트 프로그램 ex 웹브라우저)의 추가 조치 필요한 것
웹브라우저는 3xx 응답의 결과에
Location 헤더
가 있으면 Location위치로 자동 이동한다 (리 다이렉트)
클라이언트가 url을 통해 GET /event HTTP/1.1
Host: localhost:8080
으로 이벤트 페이지를 요청 했다고 하자
이때, event사이트가 new-envet라는 새로운 uri를 가진 곳으로 변경 되었다고 하면 이전 uri로 접근하는 클라이언트들에게 HTTP/1.1 301 Moved Permanently
Location:/new-event
의 응답메시지를 전달하게 된다
해당 응답 메시지를 받은 웹브라우저는 응답 결과에 Location
이 헤더에 포함된 것을 인지하고 해당 위치로 다시 이동하게 된다 (자동 리다이렉트) 이때 웹이 알아서 GET /new-event HTTP/1.1
Host:localhost:8080
을 새로운 uri에 요청하게 되고 정상적으로 연결이 되면 해당 서버에서 HTTP/1.1 200 OK
를 응답 메시지로 주게된다
종류
영구 리다이렉션 - 특정 리소스의 URI가 영구적으로(permanently) 이동
일시 리다이렉션 - 일시적인 변경
특수 리다이렉션
영구 리다이렉션 - 301
클라이언트에서 POST 메서드로 작성한 데이터와 함께 요청 메시지를 전송 POST /event HTTP/1.1
name=hello&age=20
(변경되기 전 uri로)
서버에서 응답메시지로 HTTP/1.1 301 Moved Permanentrly
Location:/new-event
를 전달 (기존 uri가 변경된 경우)
응답 메시지를 받은 웹 브라우저가 Location
을 확인하고 리다이렉트 후 GET /new-event HTTP/1.1
을 요청 (POST => GET으로 변경, 이때 갖고있던 데이터는 날라갈수 있다)
GET 요청 메시지를 받은 서버가 해당 new-envet 창을 띄어주고 응답 메시지를 보내준다 HTTP/1.1 200 OK
즉, 전달 한 데이터가 사라지고 다시 리다이렉트 받은 웹페이지에서 다시 데이터를 작성 후 전달해야 한다
영구 리다이렉션 - 308
클라이언트에서 POST 메서드로 작성한 데이터와 함께 요청 메시지를 전송 POST /event HTTP/1.1
name=hello&age=20
(변경되기 전 uri로)
서버에서 응답메시지로 HTTP/1.1 301 Moved Permanentrly
Location:/new-event
를 전달 (기존 uri가 변경된 경우)
응답 메시지를 받은 웹 브라우저가 Location
을 확인하고 리다이렉트 후 POST /new-event HTTP/1.1
을 요청 (기존의 POST를 유지하고 body도 유지해준다, 데이터 손실이 없다)
GET 요청 메시지를 받은 서버가 해당 new-envet 창을 띄어주고 응답 메시지를 보내준다 HTTP/1.1 200 OK
즉, 전달한 데이터가 없어지지 않고 메시지 바디에 유지된채로 리다이렉트 된 웹페이지로 전달된다
참고
그러나 보통 페이지가 리다이렉트 되도록 한 경우 (기존 페이지에서 새로운 페이지로 변경 된 경우) 데이터를 기존 양식과 다르게 갖는 경우가 대부분이므로 데이터를 가지고와도 쓸모없는 경우가 많다. 따라서 POST로 갖고와도 GET으로 바꿔서 새 URI를 요청하는 경우가 많다
302 Found
307 Temporary Redirect
303 See Other
정리
302, 307, 303은 일시적 리다이렉트이고, 307은 메서드를 절대 변경하지 않고(POST는 POST로 유지) 데이터도 잃어버리지 않는 것이고 VS 303은 메서드를 GET으로 확정적으로 메서드를 바꿔서 새로 요청하는 것이다
302는 기존의 영구적 리다이렉트 301과 동일하다 (메소드가 바뀔수도있고 아닐수도있고, 그에 따라서 메시지를 잃어버릴수도 있고 아닐수도 있고)
그러나 사용은 302를 많이 사용한다. 큰 문제는 없고 기본적으로 리다이렉트시 데이터를 갖고있지만 않으면 상관이 없다
PRG 사용 전
URL:/order
POST /order HTTP/1.1
Host :localhost:8080
itemId=mouse&count=1
판매 사이트의 서버가 주문을 받아서 주문데이터를 저장한다. mouse 1개
요청자에게 응답 메시지를 전달한다
HTTP/1.1 200 OK
<html>주문 완료</html>
따라서, 이러한 중복 주문 등을 막아놔야한다. 서버에서도, 클라이언트에서도
-> PRG, 일시적 리다이렉션에서 많이 사용하는 패턴
PRG 사용 후
URL:/order
POST /order HTTP/1.1
Host :localhost:8080
itemId=mouse&count=1
판매 사이트의 서버가 주문을 받아서 주문데이터를 저장한다. mouse 1개
요청자에게 응답 메시지를 전달한다
HTTP/1.1 302 Found // 기존 200 OK에서 변경되었다
Location: /order-result/orderId
요청 클라이언트는 응답메시지의 메서드가 302 일시적 리다이렉션
을 확인하고 Location
으로 리다이렉트한다
이때, 기존 요청 메시지에서 POST는 GET으로 변경어되서
GET /order-result/orderId HTTP/1.1
Host :localhost:8080
을 서버에 요청하게 된다
HTTP/1.1 200 OK
<html>주문완료</html>
연속적으로 새로고침을 하더라도 중복 주문의 위험이 존재하지 않게 된다
정리
초기에는 302의 메서드를 구상하면서 주어진 메서드를 그대로 유지하는 것이였으나, 웹브라우저 대부분이 GET으로 바꿔버렸다
이에 따라, 명확한 307, 303이 등장했다
301의 메서드 또한 302와 동일하고 이에 대한 보완으로 308이 등장
기타 리다이렉션 300, 304
클라에서 웹 창을 새로고침을 하게 되었을 때, 변경된게 없다면 304 Not Modified를 응답하게 되고 이를 받은 웹브라우저는 캐시 메모리에서 리다이렉트하게 된다 (서버에서 새로 다운 받는게 아니므로 매우 빠르다 - 웹을 켜놓고 연속으로 새로고침을 누를때와 종료 후 새로 키는 차이)
클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없는 경우
클라이언트가 해당 리소스에 대한 인증이 필요하다
WWW-Authenticate 헤더
와 함께 인증 방법을 설명한다용어참고
Unauthorized
이지만 의미는 인증이 되지 않음
이다 (단어로는 Unauthentication이 인증되지 않았다는 뜻)서버가 요청을 이해했지만 승인을 거부한 경우
요청 리소스를 찾을 수 없음
서버 내부 문제로 오류 발생, 애매할 경우 대부분 500오류
서비스 이용 불가
Retry-After헤더 필드
로 얼마뒤에 복구되는지 보낼 수도 있다참고
5xx대에러는 널포인터 Exception Error, DB에러, 서버에러, 등등 정말 시스템상으로 문제가 발생해서 셧다운이 되는 경우가 아니라면 웬만하면 5xx대 에러는 내면 안된다. 예를 들어 15세 이상 이용가능 서비스를 12세가 해당 서비스에 접근하는 경우 클라이언트 에러나 그외의 에러를 내야되고, 고객이 출금을하는데 보유 잔고보다 더 많은 금액을 출금시도하는 경우에도 마찬가지이다. 즉 서비스를 이용하는데 부적절한 접근의 경우에는 그에 맞는 에러를 내야지 서버에러를 내면 안된다. 서버에러는 실제적으로 백엔드상에서의 문제가 발생했을때만 내야한다