* 본 내용은 모든 개발자를 위한 HTTP 웹 기본 지식 강의를 참조하고 있습니다.
클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능
요청이 수신되어 처리 중(실무에서 거의 사용 X)
요청 정상 처리
요청을 완료하기 위해 유저 에이전트(브라우저)의 추가 조치 필요
웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동으로 이동(리다이렉트) 합니다.
리다이렉션에는 3가지 종류가 있습니다.
영구 리다이렉션
특정 리소스의 URI가 영구적으로 이동한 것을 의미합니다. 예를 들어 /members에서 /users로 URI가 이동한 경우 영구 리다이렉션에 속합니다. 영구적으로 URI가 변경되었기 때문에, 검색 엔진에서 URL을 변경합니다. 301 Moved Permanently, 308 Permanent Redirect 상태코드가 영구 리다이렉션에 속합니다.
301 Moved Permanently는 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있습니다(MAY). 308 Permanent Redirect는 301과 기능은 같으나, 리다이렉트시 요청 메서드와 본문을 유지하는 특징이 있습니다(처음 POST를 보내면 리다이렉트도 POST)
일시 리다이렉션
'주문 완료 후 주문 내역 화면으로 이동'과 같이 변경이 일시적으로 일어났을 때 일시 리다이렉션이라 합니다. 리소스의 URI가 일시적으로 변경된 것이기 때문에, 검색 엔진 등에서 URL을 변경하면 안됩니다. Post/Redirect/Get이라는 PRG 패턴에서 많이 사용하는 방법입니다. POST로 주문 후에 웹 브라우저를 새로고침 하면, 다시 요청이 가서 중복 주문이 일어날 수 있습니다. 이러한 경우 PRG를 사용한다면 POST로 주문 후에 주문 결과 화면을 GET 메서드로 리다이렉트 합니다. 새로고침해도 결과 화면을 GET으로 조회하도록 하는 것입니다. 302 Found, 303 See Other, 307 Temporary Redirect 상태코드가 일시 리다이렉션에 속합니다.
302 Found는 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있습니다(MAY).
303 See Other는 302와 기능은 같으나, 리다이렉트시 요청 메서드가 GET으로 변경됩니다.
307 Temporary Redirect는 302와 기능은 같으나, 리다이렉트시 요청 메서드와 본문을 유지합니다(변하면 안됨).
특수 리다이렉션
결과 대신 캐시를 사용하는 리다이렉션 방법입니다. 304 Not Modified는 캐시를 목적으로 사용합니다. 클라이언트에게 리소스가 수정되지 않았음을 알려주며, 클라이언트가 로컬 PC에 저장된 캐시를 재사용하도록 합니다. 304 응답은 로컬 캐시를 사용해야 하므로 응답에 메시지 바디를 포함하면 안됩니다.
300 Multiple Choices: 잘 사용하지 않음.
클라이언트 오류, 잘못된 문법 등으로 서버가 요청을 수행할 수 없음
클라이언트가 잘못된 요청, 데이터를 보내고 있어 오류가 나는 것으로 똑같은 재시도가 실패하는 에러입니다(서버에서 복구 불가능).
400 Bad Request
클라이언트가 잘못된 요청을해서 서버가 요청을 처리할 수 없음을 알려주는 코드입니다. 요청 구문, 메시지 등의 오류로 클라이언트가 요청 내용을 다시 검토하고 보내야하는 에러입니다.
401 Unauthorized
클라이언트가 해당 리소스에 대한 인증이 필요함을 알려주는 코드입니다. 인증(Authentication)되지 않은 상태이므로, 해당 오류 발생 시 응답에 WWW-Authenticate 헤더와 함께 인증 방법을 설명합니다.
403 Forbidden
서버가 요청을 이해했지만 승인을 거부한 경우입니다. 주로 인증 자격 증명은 있지만, 접근 권한이 불충분한 경우 해당 코드를 사용합니다.
404 Not Found
요청 리소스를 찾을 수 없다는 에러로, 요청 리소스가 서버에 없을 때 사용합니다. 또는 클라이언트가 권한이 부족한 리소스에 접근할 때 해당 리소스를 숨기고 싶을 때 사용합니다.
서버 오류, 서버가 정상 요청을 처리하지 못함
서버에 문제가 있기 때문에 재시도하면 성공할 가능성이 있는 오류입니다(복구 가능). 5xx 에러는 서버에 심각한 에러가 있을 때 사용해야 합니다.
클라이언트의 요청에서 서로 약속한 HTTP API 스펙은 만족했지만, 그래서 비즈니스 로직까지 정상 수행했지만, 비즈니스 로직의 결과가 성공으로 처리되지 않을 수 있습니다. 이런 경우 400을 반환하게 되면, 클라이언트 개발자는 분명 서로 약속한 API 스펙을 다 지켰는데, 클라이언트 개발자에게 잘못 개발하셨어요. 라고 이야기하는 것과 같습니다. 그래서 이렇게 복잡한 비즈니스 로직이 들어가는 경우 200 OK로 응답하면서 결과에 내부 비즈니스 응답 코드를 정의해서 함께 전달합니다. 다음과 같이 응답 코드를 만들고 데이터도 한번 감싸서 전달하는 것이지요. 이것을 봉투 패턴(Envelope pattern)이라 합니다. (김영한님 답변 중)
500 Internal Server Error
서버 내부 문제로 오류가 발생했다는 뜻으로, 애매한 경우 500 오류를 사용합니다.
503 Service Unavailable
서비스가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없는 경우입니다. Retry-After 헤더 필드로 얼마 뒤에 복구되는지도 보낼 수 있습니다.
1. 서로 약속한 HTTP API 스펙을 만족한다. -> 200, 만족하지 않는다. -> 400
2. 비즈니스 로직이 정상 수행되지만, 다양한 결과가 존재한다.(승인, 거절 등등) -> 200 + 비즈니스 코드 반환(봉투 패턴)
3. 비즈니스 로직을 수행하다가 내부에서 시스템 예외나 NullPointerException 등등 비즈니스와 관계없는 시스템 예외가 발생한다. -> 500
참고: 다양한 비즈니스 응답이 있는 복잡한 비즈니스 로직이 있는 HTTP API는 봉투 패턴을 고려하고, 비즈니스 로직이 거의 없는 단순한 조회에서는 봉투 패턴을 고려하지 않는다.