HTTP - 6 HTTP 상태 코드
해당 자료는 인프런 김영한 선생님의 모든 개발자를 위한 HTTP 웹 기본 지식 강의노트입니다.
1. HTTP 상태코드 소개
상태코드란 클라이언트가 보낸 요청의 처리 상태를 응답해서 알려주는 기능을 말합니다.
- 1xx(Informational) : 요청이 수신되어 처리중
- 2xx(Successful) : 요청 정상 처리
- 3xx(Redirection) : 요청을 완료하려면 추가 행동이 필요
- 4xx(Client Error) : 클라이언트 오류, 잘못된 문법등으로 서버가 요청을 수행할 수 없을 때
- 5xx(Server Error) : 서버 오류, 서버가 정상 요청을 처리하지 못함.
만약 모르는 상태 코드가 나타나면?
예를 들어 299라던지 451같은 상태코드가 나타나면 상위상태코드로 이해하면 됩니다.
299는 2xx니까 요청이 정상처리된 것.
451은 4xx니까 클라이언트 오류라고 생각하시면 됩니다.
1xx(Informational)
요청이 수신되어 처리중
거의 사용하지 않으므로 생략합니다.
2. 2xx(Successful)
- 200 OK
- 201 Created
- 202 Accepted
- 204 No Content
200 OK
요청 성공입니다.
제일 많이 접할 수 있는 요청상태입니다.
201 Created
요청이 성공해서 새로운 리소스가 생성된 것입니다.
서버에서는 Location이라는 것에 정보를 반환합니다.
202 Accepted
요청이 접수되었지만 처리가 되지 않은 것입니다.
보통 배치 처리같이 1시간 뒤에 처리해야하는 작업 등에 사용됩니다.
204 No Content
서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없을 때입니다.
예를 들어 웹 문서 편집기에서 save 버튼을 누르면 서버에서 보낼 데이터가 없으므로 No Content을 사용하면 됩니다.
물론 성공 실패 여부는 개발자가 직접 정해줘야합니다.
3. 3xx - 리다이렉션
리다이렉션은 요청이 들어왔을 때 추가적인 조치가 필요할 때 씁니다.
- 300 Multiple Choices
- 301 Moved Permanently
- 302 Found
- 303 See Other
- 304 Not Modified
- 307 Temporary Redirect
- 308 Permanent Redirect
리다이렉션
웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면 Location 위치로 자동이동합니다.
리다이렉션은 3가지 종류가 있습니다.
- 영구 리다이렉션 - 특정 리소스의 URI가 영구적으로 이동
- /members -> /users
- /event -> /new-event
- 일시 리다이렉션 - 일시적인 변경
- 주문 완료 후 주문 내역 화면으로 이동
- PRG: Post/Redirect/Get <- 뒤에서 설명하겠습니다.
- 특수 리다이렉션
- 결과 대신 캐시를 사용.
영구 리다이렉션
301, 308입니다.
위의 예시처럼 리소스의 URI가 영구적으로 이동할 때 사용하는 상태코드입니다.
원래의 URL을 사용하지 않고, 검색 엔진 등에서도 변경을 인지합니다.
- 301 Moved Permanently
- 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수도 있습니다.(거의 변경된다고 보면 됩니다.)
특이점으로 리다이렉트 이후 GET으로 요청을 보내고 메시지는 전달되지 않는다는 점입니다.
- 308 Permanent Redirect
- 301과 같은 기능을 하지만, 리다이렉트시 요청 메서드와 본문을 유지합니다.
리다이렉트 이후 POST 요청을 보내고 메시지를 유지하여 보낸다는 점이 특이점입니다.
이 둘은 잘 사용하지 않고 일시적인 리다이렉션을 더 많이 사용한다고 합니다.
일시적인 리다이렉션
302, 307,303이 있습니다.
URL을 변경하면 안됩니다.
- 302 Found
- 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있습니다.
- 스펙의 오류때문에 최근에는 잘 사용하지 않지만, 옛날에 많이 쓰였습니다.
- 307 Temporary Redirect
- 302와 기능은 같습니다.
- 리다이렉트시 요청 메서드와 본문을 유지합니다.(요청 메서드를 변경하면 안됩니다.)
- 303 See Other
- 302와 기능은 같지만 리다이렉트시 요청 메서드가 GET으로 변경됩니다.
만약 웹페이지에서 주문을 누른 뒤에 새로고침을 하면 주문이 또 들어갈 것입니다.
이러한 것을 방지하기 위한 패턴이 PRG(Post/Redirect/GET)패턴입니다.
1
PRG: 사용 전
PRG 사용했을 때 로직입니다.
- POST로 주문 후에 주문 결과 화면은 GET 메서드로 리다이렉트
- 새로고침해도 결과화면을 GET으로 조회
- 중복 주문 대신에 결과 화면만 GET으로 요청
즉 웹페이지를 반환하여 그 화면에서 새로고침을 해도 상관없게 만드는 것 같습니다.
결국은 302 보다는 307, 303을 쓰는게 좋습니다.
자동 리다이렉션시에 GET으로 변해도 되면 302를 사용해도 된다고 합니다.
기타 리다이렉션
300, 304
300 Mutiple Choices : 안쓰입니다.
304 Not Modified : 캐시를 목적으로 사용합니다.
클라이언트에게 리소스가 수정되지 않았음을 알려줍니다. 따라서 클라이언트는 로컬 PC에 저장된 캐시를 재사용합니다. (캐시로 리다이렉트)
304 응답은 응답에 메시지 바디를 포함하면 안됩니다.
조건부 GET,HEAD 요청시 사용합니다.
캐시에 대한 내용은 다음에 쓰겠습니다.
4. 4xx, 5xx 클라이언트, 서버 오류
4xx(Client Error)
클라이언트 오류
- 클라이언트의 요청에 잘못된 문법등으로 서버가 요청을 수행할 수 없을 때입니다.
- 오류의 원인이 클라이언트에 있습니다.
클라이언트가 이미 잘못된 요청, 데이터를 보내고 있기에 요청을 재시도해도 결과는 실패합니다.
400 Bad Request
클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없습니다.
- 요청 구문, 메시지, URL 오타 등을 말합니다.
- 요청 파라미터가 잘못되거나, API 스펙이 맞지 않을 때 입니다.
401 Unauthorized
클라이언트가 해당 리소스에 대한 인증이 필요할 때입니다.
예를 들어 로그인(인증 - Authentication), 권한부여(특정 리소스에 접근할 수 있는 권한 - 인가 - Authorization) 등의 상황이 있습니다.
403 Forbidden
서버가 요청을 이해했지만 승인을 거부함.
예를 들어서 일반유저가 관리자 권한을 요청시 등이 있습니다.
404 Not Found
요청 리소스를 찾을 수 없음.
요청 리소스가 서버에 없거나 권한이 없는 유저가 해당 리소스에 접근할 때 막기위해 사용합니다.
500 Internal Server Error
서버 내부 문제로 오류가 발생할 때 입니다.
애매하면 500 오류를 내면 됩니다.
503 Service Unavailable
서비스 이용 불가상태입니다.
일시적인 과부하 또는 업데이트 등으로 서버를 잠시 막아놓을 때 사용합니다.
Retry-After 헤더 필드로 얼마뒤에 복구되는지 보낼 수 있습니다.
결론
403과 404 둘 중 아무거나 써도 됩니다. 숨기고 싶을 땐 404를 사용하고 오류를 정확히 알려주고 싶으면 403을 사용합니다.
그리고 어떤 사용자가 조건을 만족하지 못해서 보류상태로 놔야한다고 했을 때 200을 해야할지 400을 상태코드로 해야할 지는 클라이언트와 약속이 되어 있으면 200을 내고 클라이언트가 이러한 사실을 모른다고 했을 때는 400을 오류로 내놓습니다.
왜냐하면 만약 만 19세가 넘은 유저가 19세 인증을 안한상태로 리소스에 접근하려고 하는데 클라이언트도 이러한 사실을 알면 200을 상태코드로 반환합니다.
이러한 사실을 모르면 400을 상태코드로 반환합니다.