HTTP 상태코드 정리
서론
항상 헷갈리는 내용이라 따로 정리해봤습니다.
API 개발하면서 클라이언트와 소통할 때 상태코드를 제대로 알고 있으면 디버깅이 훨씬 수월합니다. 특히 프론트엔드 개발자와 협업할 때 “이 API는 성공하면 200, 리소스 생성되면 201, 없으면 404 보낼게요”라고 명확히 소통할 수 있거든요.
100번대
100번대 코드는 프로토콜을 교체해도 된다거나 계속 요청을 보내도 된다는 식의 정보성을 띄고 있는 상태를 의미합니다.
다만 실무에서 이런 코드를 직접 만날 일은 거의 없습니다.
200번대 - 성공
200번대 코드들은 클라이언트가 요청한 작업을 서버가 성공적으 로 수행했다는 것을 알려주는 코드입니다.
브라우저 개발자 도구의 네트워크 탭에서도 깔끔한 초록색으로 표시됩니다.
200 OK
요청이 성공적으로 처리되었음을 의미합니다. 가장 많이 보게 되는 응답코드입니다.
201 Created
요청이 성공적으로 수행되었고, 그로 인해 새로운 리소스가 생성되었다는 것을 의미합니다.
주로 POST 요청에 대한 응답으로 사용됩니다.
서버: 리소스 잘 만들어졌어요204 No Content
요청이 성공적으로 수행되었고, 응답 본문에 보낼 컨텐츠가 없음을 의미합니다.
DELETE 요청이 성공했을 때 주로 사용됩니다.
서버: 리소스 삭제 잘 되었어요300번대 - 리다이렉션
300번대 코드들은 리다이렉션에 관련된 상태들을 의미합니다.
서버: 요청한 리소스는 이쪽으로 가면 있어요301 Moved Permanently
브라우저는 301 코드를 받으면 HTTP 헤더에 들어있는 Location 필드를 찾아보고, 해당 필드가 존재할 경우 Location 필드에 담긴 URL로 자동으로 리다이렉션합니다.
HTTP 프로토콜로 접속한 사용자를 HTTPS 프로토콜을 사용해야만 접근 가능한 포트로 보내버릴 때에도 많이 사용합니다.
304 Not Modified
클라이언트가 요청한 리소스가 이전 요청 때와 비교해보았을 때 전혀 달라진 점이 없다는 것을 의미합니다.
변한 게 없으므로 브라우저의 캐싱 리소스를 사용하기 때문에 네트워크 비용을 줄일 수 있습니다.
400번대 - 클라이언트 오류
400번대 코드들은 클라이언트가 서버에게 보낸 요청이 잘못된 경우를 의미합니다.
프론트엔드 개발자가 보통 주춤거리는 영역입니다.
400 Bad Request
가장 많이 만날 수 있는 400번대 코드 중 하나이며, 밑도 끝도 없이 “클라이언트가 요청을 잘못 날림”이라는 의미입니다.
대부분 요청 파라미터가 잘못되었거나, 필수 값이 빠졌거나, 형식이 맞지 않을 때 발생합니다.
401 Unauthorized
인증되지 않은 사용자가 인증이 필요한 리소스를 요청하는 경우에 발생하는 응답코드입니다.
주로 로그인 관련 로직에서 많이 발생합니다.
서버: 인증이 필요해요403 Forbidden
클라이언트가 접근이 금지된 리소스를 요청했음을 의미합니다. 인증과는 무관합니다.
- 401 (Unauthorized): “누구세요?” (로그인 필요)
- 403 (Forbidden): “접근 금지!” (로그인은 했으나 권 한 없음)
HTTPS 프로토콜로만 접근해야 하는 리소스에 HTTP 프로토콜을 사용하여 접근했을 경우에 서버에서 403 응답을 보내주기도 합니다.
서버: 이 리소스에 대한 권한이 없어요404 Not Found
요청한 리소스가 존재하지 않음을 의미합니다. 가장 유명한 에러 코드죠.
405 Method Not Allowed
현재 리소스에 맞지 않는 메소드를 사용했음을 의미합니다.
예를 들어 GET만 지원하는 엔드포인트에 POST 요청을 보낸 경우입니다.
서버: 그 메소드는 지원하지 않아요406 Not Acceptable
요청 헤더에서 알맞은 컨텐츠 타입이 없다는 것을 의미합니다.
서버: 요청한 그 컨텐츠 타입은 제공할 수 없어요408 Request Timeout
클라이언트와 서버의 연결은 성사되었지만 요청의 본문이 계속 서버에 도착하지 않는 상황을 의미합니다.
서버: 요청이 계속 도착하지 않고 있어요429 Too Many Requests
클라이언트가 서버에 너무 많은 요청을 보내는 경우에 발생합니다.
유료 API를 사용하는 경우에는 현재 금액으로 사용할 수 있는 API 요청 횟수를 초과해서 “돈을 더 내세요”라는 의미로 사용되기도 합니다.
서버: 요청을 너무 많이 보냈어요 (응답 헤더에 Retry-After 포함됨)500번대 - 서버 오류
500번대 코드들은 클라이언트가 아닌 서버에서 뭔가 문제가 발생한 경우입니다.
백엔드 개발자가 보통 주춤거리는 영역입니다.
500 Internal Server Error
백엔드 어플리케이션 내에서 알 수 없는 에러가 발생했다는 의미입니다.
보통 예외 처리가 안 된 코드에서 에러가 터졌을 때 발생합니다.
502 Bad Gateway
502 코드는 백엔드 어플리케이션이 죽은 상황입니다.
게이트웨이라는 단어가 들어간 이유는 대부분의 엔터프라이즈급 개발의 경우 클라이언트와 서버가 직접 연결된 것이 아니라, 중간에 프록시 서버나 로드밸런서 같은 “문지기”들이 존재하는데, 이 “문지기”들과 백엔드 어플리케이션 간의 통로를 게이트웨이라고 부르기 때문입니다.
중간 서버: 백엔드 서버 지금 죽은 것 같아요503 Service Unavailable
서버가 요청을 처리할 준비가 되지 않았음을 의미합니다.
일반적으로 서버에 부하가 심해서 현재 요청을 핸들링할 수 있는 여유가 없는 경우에 많이 사용됩니다. 응답 헤더의 Retry-After 필드를 사용하여 “이 시간 이후에 다시 요청해봐”라는 의미를 클라이언트에게 전달해줄 수 있습니다.
중간 서버: 백엔드 서버 지금 과부하 상태래요504 Gateway Timeout
408과 마찬가지로 요청에 대한 타임아웃을 의미합니다.
- 502 (Bad Gateway): 백엔드 서버가 죽었거나 응답을 거부함
- 504 (Gateway Timeout): 백엔드 서버가 응답을 늦게 줌 (타임아웃)
예를 들면 Nginx나 Apache Web Server가 일정 시간 응답이 오지 않을 경우, 클라이언트에게 내려주는 응답코드입니다.
중간 서버: 백엔드한테 여러 번 연락했는데 시간 초과 떴어요결론
HTTP 상태코드는 단순한 숫자가 아니라 클라이언트와 서버 간의 소통 언어입니다.
실무에서 API를 개발하다 보면, 적절한 상태코드를 사용하는 것이 생각보다 중요하다는 것을 느끼게 됩니다. 특히 프론트엔드 개발자와 협업할 때 명확한 상태코드를 반환하면 오류 처리 로직을 작성하기가 훨씬 수월해집니다.
경험상 가장 많이 헷갈리는 것은 401과 403의 차이입니다. 저도 초반에는 둘 다 “접근 불가”로만 생각했는데, 명확히 구분해서 사용하니 프론트엔드에서 에러 메시지를 처리하기가 훨씬 쉬워졌습니다.
- 401: “로그인 페이지로 보내기”
- 403: “권한 없음 메시지 표시”
이렇게 클라이언트 측에서 명확한 액션을 취할 수 있게 되거든요.
다만 완벽하게 RESTful 하게 모든 상태코드를 사용하려다 보면 오히려 복잡해질 수 있습니다. 팀 내에서 자주 사용하는 상태코드를 정리해두고, 일관성 있게 사용하는 것이 더 중요합니다.
참고 자료:
https://ko.wikipedia.org/wiki/HTTP_상태_코드
https://evan-moon.github.io/2020/03/15/about-http-status-code/
