Http Status Code 정리

API 명세서를 작성하면서 헷갈렸었던 Http Status 정리


Http Status code는 왜 존재 할까?

프론트엔드와 백엔드는 어떤 방식으로 통신을 할 것인지 부터 시작해서 리소스의 생성과 삭제는 어떻게 정의할 것인지, 프론트엔드에서 요청한 백엔드 작업의 성공/실패 여부는 어떻게 알려줄 것인지 등 많은 규칙들을 정의해야 한다.

이러한 규칙들을 정의할 때 몇 가지 가이드라인이 존재하는데, 이때 Http Status Code가 대표적인 가이드라인 중 하나이다.

말 그대로 가이드라인이기 때문에, 이것을 지키지 않는다고 프로그램이 작동하지 않는 것은 아니다. 그러면 왜 만든 것일까?


API란?

API(Application Programming Interface)는 응용 프로그램을 제작할 때 필요한 기능들을 일련의 인터페이스로 제공하는 것을 의미한다. 즉, 프로그램 간의 통신을 위한 인터페이스라고 할 수 있다.

클라이언트가 서버에게 뭔가를 요청할 때 특정 규칙으로 정의된 API를 사용하여 서버의 리소스를 사용하게 되는데, HTTP를 사용하여 통신할 경우 이 API를 엔드포인트라는 특정한 URL을 사용하여 정의하게 되고

서버는 일관된 방식으로 이 엔드포인트로 들어온 요청에 대한 응답을 보내야 한다.

이때 Http Status Code는 클라이언트가 보냈던 요청의 수행 결과를 의미하는 일종의 약속이라고 볼 수 있다.

클라이언트에서 사용하는 모든 Http 통신 라이브러리들은 올바른 Http Status Code사용을 가정하고 설계되었기 때문에 올바르지 않은 Status Code를 사용하게 된다면 프론트엔드 측에서 불필요한 작업들을 해줘야 하는 불편함이 있을 것이므로 올바르게 사용해야 한다.


Http Status Code 종류

모든 Http Status Code는 5개의 클래스로 분류된다. 첫 번째 숫자는 응답의 클래스를 정의하고 마지막 두 자리는 클래스나 분류 역할을 하지 않는다.

각 클래스마다 많은 상태 코드가 있지만 자주 쓰는 것만 정리해보자!


  • 1xx(정보) : 프로토콜을 교체해도 된다고나 계속 요청을 보내도 된다는 정보성을 띄고 있는 상태 거의 사용 안함
  • 2xx(성공) : 클라이언트가 요청한 작업을 서버가 성공적으로 실행한 상태

    • 200 OK
      • 단순 작업 성공을 의미한다.
      • 대부분의 경우 클라이언트는 자신이 요청한 작업이 정확히 어떤 작업인지 알고 있기 때문에, 서버에서 “니가 보낸 요청이 성공했어”라는 정보만 알려주면 굳이 그 이상의 디테일한 정보는 알 필요가 없다. 그래서 이 상태 코드 하나만으로 모든 API 응답 성공 상태를 퉁치는 경우가 대다수이다.
    • 201 Created 주로 회원가입
      • 상태 코드 201은 말 그대로 요청이 정상적으로 수행되었고, 그로 인해 리소스가 새롭게 생성되었다는 것을 의미한다.
      • 클라이언트가 서버에게 요청을 보내서 새로운 리소스를 생성하는 상황은 굉장히 흔한데, 그 중 필자가 경험했던 대표적인 사례는 바로 “회원가입”이다. 결국 클라이언트의 회원가입 요청으로 인해 데이터베이스에 새로운 유저의 로우가 생성되었기 때문에, 이런 경우가 201 상태 코드가 아주 잘 들어맞는 케이스라고 볼 수 있다.
    • 204 No Content 삭제
      • 요청이 정상적으로 수행되었고, 이 요청과 관련되었던 컨텐츠 또한 더 이상 깔끔하게 존재하지 않음을 의미한다.
      • 이 상태 코드는 클라이언트가 서버에게 요청을 보내서 뭔가를 삭제해야하는 응답으로 사용될 수 있고, 이번에도 삭제하는 API에 이 코드를 사용했다.
  • 3xx(리다이렉션) : 클라이언트가 요청한 리소스가 옮겨졌거나 삭제되어서 등의 이유로 정상적인 방법으로 해당 리소스에 접근할 수 없고 다른 URL을 통해서 그 리소스에 접근해야 하는 경우

    • 301 Moved Permanetly
      • 301 Redirect라는 별칭으로 불리기도 할 만큼 리다이렉션을 위한 코드 중 가장 많이 사용된다.
      • 브라우저는 자신의 대한 요청의 응답으로 301을 받으면 HTTP 헤더에 들어있는 Location 필드를 찾아보고, 해당 필드가 존재할 경우 Location 필드에 담긴 URL로 자동으로 리다이렉션한다.
      • 구글에서는 이 코드를 받을 경우 자동으로 페이지 정보를 갱신하도록 하므로, Search Engine Optimizer 관점에서 이 코드를 잘 사용하는 것이 중요하다고 한다.
      • 이외에도 Http 프로토콜로 접속한 사용자를 Https 프로토콜로 사용해야만 접근 가능한 포트로 보내버릴 때 많이 사용된다고 한다.
    • 304 Not Modified
      • 클라이언트가 요청한 리소스가 이전 요청 때와 비교했을 때 달라진 점이 없다는 것을 의미한다.
      • 이 코드를 받을 경우, 클라이언트는 서버에게 리소스를 재전송 받을 필요가 없기에 캐싱해놓았던 걸 사용하게 되고 통신 로드를 줄일 수 있다.
  • 4xx(클라이언트 오류) : 클라이언트가 서버에게 보낸 요청이 잘못 된 경우
    • 400 Bad Request
      • 클라이언트가 요청을 잘 못 날렸다는 것을 의미
    • 401 Unauthorized
      • 인증이 필요한 리소스를 요청 할 경우, 인증이 필요하다는 것을 의미한다.
      • 보통 로그인이 필요한 API를 비회원 사용자가 사용하려 할 때 발생한다.
      • 로그인 페이지로 리다이렉션 해주기도 한다.
    • 403 Forbidden
      • 클라이언트가 접근이 금지된 리소스를 요청했다는 것을 의미한다.
      • 401 Unauthroized와 헷갈리는데 401은 말그대로 인증되지 않았다는 것을 의미하며 서버가 클라이언트한테 “신원을 밝혀!” 라고 말하는 것이다.
      • 403은 리소스를 요청한 사용자가 누군지 관심이 없고, 인증이 되었던지 말던지 이 리소스를 요청하는 것은 무조건 금지라고 말하는 것이다.
      • Https로만 접근해야 하는 리소스에 Http로 접근한 경우 이 코드를 사용한다고 한다.
    • 404 Not Found
      • 요청한 리소스가 존재하지 않다는 것을 의미한다.
    • 405 Method Not Allowed
      • 현재 리소스에 맞지않는 메소드를 사용했음을 의미한다.
      • 백엔드 프레임워크에서는 특정 컨트롤러에 해당 메소드를 사용하는 로직이 없다면 자동으로 이 코드를 사용한다고 한다.
    • 406 No Acceptable
    • 408 Request Timeout
      • 클라이언트와 서버 간의 연결은 정상적이지만 요청의 본문이 서버에 도착하지 않는 상황을 의미한다.
      • 서버가 아무리 기다려도 클라이언트의 요청을 받지 못할 때 사용한다.
    • 409 Conflict
      • 클라이언트의 요청이 현재 서버의 상태와 충돌일 경우를 의미한다.
      • PUT에 대한 응답으로 발생할 가능성이 가장 높다.
      • 서버에 있는 기존 파일보다 오래된 파일을 업로드 할 때 발생할 수 있다.
  • 5xx(서버 오류) : 서버에서 오류가 난 경우
    • 500 Internal Server Error 제일 많이 본 에러코드다..
      • 백엔드 어플리케이션 내부에서 알 수 없는 에러가 발생했다는 의미이다.
      • 원인을 클라이언트에게 알려줄수 없는 경우가 대부분이다.
    • 502 Bad Gateway
      • 백엔드 어플리케이션이 사망한 경우에 가장 흔히 발생ㅎ안다.
      • 보통 백엔드 어플리케이션 앞단에 Nginx같은 서버 엔진이나 로드밸런서를 두게 되며 이를 프록시 서버라고 한다.
      • 백엔드 어플리케이션과 프록시 서버 사이를 Gateway라고 한다.
      • 백엔드 어플리케이션이 사망하면 프록시 서버는 아무 응답도 받지 못하게 되고 클라이언트에게 502 Bad Gateway라고 응답을 보내는 것이다.
    • 503 Service Unavailable
      • 서버가 요청을 처리할 준비가 되지 않았음을 의미한다.
      • 보통 서버에 부하가 심해서 현재 요청을 핸들링 할 여유가 없는 경우에 많이 사용한다.
      • 502와 비슷한 느낌이지만 좀더 일시적인 상황을 의미한다.
    • 504 Gateway Timeout
      • 408과 다른 점은, 클라이언트에서 보낸 요청 때문에 Timeout이 발생하는 것이 아니라 백엔드 아키텍쳐 내부에서 서버끼리 주고받는 요청에서 발생한다는 차이가 있다.
      • Nginx가 백엔드 어플리케이션에 클라이언트 요청을 전달했는데, 백엔드 어플리케이션이 응답을 하지 않는 경우 Nginx가 클라이언트에게 504를 전달한다.

최대한 어떤 경우에 이 코드가 사용되는지, 예시를 생각해보며 이해를 하려고 하자 :)

참고

  • https://developer.mozilla.org/ko/docs/Web/HTTP/Status
  • https://evan-moon.github.io/2020/03/15/about-http-status-code/