상태 코드 등급
고친 사람 github-actions[bot]
상태 코드 등급은 상태 코드를 맨 앞 숫자 하나로 다섯 묶음에 나눕니다. 상태 코드는 웹 서버가 응답마다 붙이는 세 자릿수 결과 번호입니다. 맨 앞 숫자만 보면 결과의 큰 뜻을 알 수 있습니다. 그래서 받는 프로그램은 처음 보는 코드를 받아도 다음에 할 일을 정할 수 있습니다.
쉽고 빠른 이해
등급은 상태 코드의 맨 앞 숫자가 알려 주는 큰 뜻입니다. 상태 코드는 서버가 응답마다 붙이는 세 자릿수 결과 번호입니다. 404 의 4 는 요청한 쪽에 문제가 있다는 뜻입니다. 4 로 시작하는 코드를 묶어 4xx 라고 적습니다.
상태 코드는 수십 가지라 다 외울 수 없습니다. 새 코드도 계속 생깁니다. 등급만 맞춰 읽으면 처음 보는 코드도 큰 뜻은 놓치지 않습니다.
어떻게 도는가:
- 서버가 상태 코드를 고릅니다. 맨 앞 숫자가 등급입니다
- 받는 쪽은 먼저 등급을 봅니다. 성공이면 거기서 끝냅니다. 실패면 원인을 가립니다
- 뒤의 두 숫자는 아는 코드일 때만 더 자세히 읽습니다
대가가 있습니다. 등급은 큰 갈래만 알려 줍니다. 같은 4xx 라도 다시 보내면 되는 경우와 고쳐서 보내야 하는 경우가 갈립니다. 그래서 뒤의 두 숫자까지 봐야 할 때가 있습니다.
상세
우편번호는 앞 숫자가 지역을 정합니다. 뒤 숫자를 몰라도 앞 숫자만 보면 어느 지방으로 보낼지는 정할 수 있습니다. 우체국은 그 지방에 닿은 다음에야 뒤 숫자를 읽습니다.
상태 코드 등급도 이처럼 맨 앞 숫자로 큰 갈래를 정합니다. 뒤의 두 숫자를 몰라도 성공인지 실패인지는 알 수 있습니다. 이 절은 그 갈래가 무엇이고 받는 쪽과 보내는 쪽이 어떻게 쓰는지를 봅니다.
HTTP(HyperText Transfer Protocol, 하이퍼텍스트 전송 프로토콜)는 요청을 보내고 응답을 받는 규약입니다. 요청을 보내는 쪽은 클라이언트, 받아서 답하는 쪽은 서버입니다. 브라우저나 앱, 다른 서버를 부르는 백엔드 코드가 클라이언트입니다.
서버는 응답마다 결과를 세 자릿수 번호로 알립니다. 이 번호가 상태 코드입니다. 200 은 요청을 처리했다는 뜻입니다. 404 는 찾는 대상이 없다는 뜻입니다.
상태 코드 등급은 이 코드들을 맨 앞 숫자로 나눈 묶음입니다. 영어로는 status code class 라고 부릅니다. 맨 앞 숫자가 2 인 200, 201, 204 는 모두 같은 등급입니다.
등급은 숫자 뒤에 xx 를 붙여 적습니다. x 는 어떤 숫자든 들어갈 수 있다는 표시입니다. 그래서 2xx 는 200 부터 299 까지를 한 번에 가리킵니다.
다섯 등급
상태 코드는 100 부터 599 까지입니다. 맨 앞 숫자는 1 부터 5 까지라 등급도 다섯입니다. 아래 표는 등급마다 무엇을 알리고 받은 쪽이 무엇을 하는지를 나란히 놓았습니다.
| 등급 | 이름 | 알리는 것 | 받은 쪽이 할 일 | 흔히 보는 코드 |
|---|---|---|---|---|
| 1xx | Informational · 정보 | 요청을 받았고 처리가 이어진다 | 최종 응답을 더 기다린다 | 100 · 101 |
| 2xx | Successful · 성공 | 요청을 받아 처리했다 | 결과를 쓴다 | 200 · 201 · 204 |
| 3xx | Redirection · 리다이렉션 | 끝내려면 클라이언트가 무언가를 더 해야 한다 | 알려 준 곳으로 다시 간다 | 301 · 302 · 304 |
| 4xx | Client Error · 클라이언트 오류 | 요청에 문제가 있다 | 요청을 고친다 | 400 · 401 · 404 |
| 5xx | Server Error · 서버 오류 | 서버가 처리하지 못했다 | 나중에 다시 해 본다 | 500 · 502 · 503 |
표의 마지막 두 줄이 가장 자주 쓰입니다. 4xx 와 5xx 는 둘 다 실패지만 누구 쪽에 원인이 있는지가 다릅니다. 이 차이는 아래 「4xx 와 5xx 를 가르는 기준」에서 다시 봅니다.
처음 보는 코드를 읽는 법
상태 코드는 나중에 새로 늘어날 수 있습니다. 그래서 클라이언트가 모든 코드의 뜻을 알 필요는 없습니다. 대신 등급은 반드시 알아야 합니다.
모르는 코드를 받으면 그 등급의 x00 을 받은 것처럼 다룹니다. x00 은 맨 앞 숫자는 두고 뒤의 두 숫자를 0 으로 채운 코드입니다. 471 을 처음 보면 400 을 받은 것처럼 다룹니다. 532 를 처음 보면 500 으로 다룹니다.
이 규칙은 코드로 옮기면 나눗셈 한 번입니다. 아래 자바 코드는 471 을 받았을 때 등급과 대신 읽을 코드를 구합니다.
int status = 471;
int cls = status / 100; // 4
int base = cls * 100; // 400
정수를 100 으로 나누면 뒤의 두 숫자가 떨어져 나갑니다. 맨 앞 숫자만 남습니다. 거기에 다시 100 을 곱하면 x00 이 됩니다.
1xx 중간 응답
1xx 는 최종 응답이 아닙니다. 처리가 아직 끝나지 않았다는 중간 소식입니다. 한 요청에는 2xx 부터 5xx 중 하나인 최종 응답이 딱 하나 돌아옵니다. 1xx 는 그 앞에 몇 번이든 올 수 있습니다.
대표가 100 Continue 입니다. 요청에 실어 보내는 데이터를 본문이라고 부릅니다. 파일을 올린다면 그 파일이 본문입니다. 100 Continue 는 큰 본문을 올리기 전에 서버가 받아 줄지부터 묻는 데 씁니다.
묻는 데는 헤더를 씁니다. 헤더는 요청에 붙는 이름과 값의 짝입니다. 본문보다 앞에 실립니다. 클라이언트는 Expect: 100-continue 라는 헤더를 붙여 헤더만 먼저 보냅니다. 서버가 받아 줄 수 있으면 100 Continue 로 답합니다.
sequenceDiagram
participant 클라이언트
participant 서버
클라이언트->>서버: 헤더만 먼저 보냄
서버-->>클라이언트: 100 Continue
클라이언트->>서버: 본문을 보냄
서버-->>클라이언트: 201 Created
그림 끝의 201 Created 가 이 요청의 최종 응답입니다. 요청대로 새것을 만들었다는 2xx 응답입니다.
101 Switching Protocols 도 1xx 입니다. 같은 연결을 다른 규약으로 바꾸겠다고 알릴 때 씁니다. 웹소켓으로 넘어갈 때 이 응답이 오갑니다.
3xx 가 요구하는 추가 동작
3xx 는 요청을 끝내려면 클라이언트가 무언가를 더 해야 한다는 뜻입니다. 가장 흔한 것은 다른 주소로 다시 요청하라는 것입니다. 이 동작을 리다이렉션이라고 부릅니다.
새 주소는 Location 헤더에 실려 옵니다. 브라우저는 3xx 와 이 헤더를 받으면 사용자가 손대지 않아도 새 주소로 다시 요청합니다.
3xx 가 모두 주소를 옮기라는 뜻은 아닙니다. 304 Not Modified는 클라이언트가 전에 받아 저장해 둔 사본이 아직 최신이라는 뜻입니다. 이때 클라이언트가 할 일은 새 주소로 가는 것이 아니라 가진 사본을 다시 쓰는 것입니다.
4xx 와 5xx 를 가르는 기준
두 등급은 원인이 어느 쪽에 있는지로 갈립니다. 4xx 는 요청 자체에 문제가 있다는 뜻입니다. 빠진 값, 없는 주소, 모자란 권한이 여기에 듭니다.
5xx 는 서버가 요청을 처리하지 못했다는 뜻입니다. 요청 쪽에는 잘못이 보이지 않습니다. 서버 코드의 예외, 뒤에 있는 다른 서버의 장애, 일시적인 과부하가 여기에 듭니다.
이 차이가 다시 보낼지를 정합니다. 4xx 는 같은 요청을 그대로 다시 보내면 대개 같은 실패가 납니다. 요청을 고쳐야 합니다. 5xx 는 서버 사정이 풀리면 같은 요청이 성공할 수 있습니다.
다만 5xx 라고 아무 요청이나 다시 보내면 안 됩니다. 서버가 일을 반쯤 해 두고 실패했을 수 있기 때문입니다.
그래서 다시 보내기는 여러 번 보내도 한 번 보낸 것과 결과가 같은 요청에 한정하는 것이 안전합니다. 이런 성질을 멱등성이라고 부릅니다. 조회하는 GET 은 멱등합니다. 새로 만드는 POST 는 대개 멱등하지 않습니다.
등급만으로 다 가려지지는 않습니다. 429 Too Many Requests는 4xx 지만 요청을 고칠 일이 없습니다. 너무 자주 보냈다는 뜻이라 잠시 기다렸다 다시 보내면 됩니다. 등급으로는 큰 방향만 정합니다. 이런 코드는 따로 다룹니다.
응답을 만드는 쪽에서 등급 고르기
API(Application Programming Interface)는 프로그램이 다른 프로그램을 부르는 약속입니다. 백엔드에서 API 응답을 만들 때는 등급부터 고릅니다. 성공인지, 요청 쪽 잘못인지, 서버 쪽 잘못인지를 먼저 정하고 그다음에 코드를 좁힙니다.
등급을 잘못 고르면 응답이 거쳐 가는 프로그램들이 모두 틀리게 읽습니다. 실패를 200 으로 보내고 응답 본문에만 오류를 적으면 클라이언트 라이브러리는 성공으로 받아들입니다.
응답을 저장해 두었다가 다음 요청에 다시 내주는 장치를 캐시라고 부릅니다. 캐시도 200 을 보고 그 응답을 성공으로 저장합니다. 그러면 같은 실패가 계속 퍼집니다.
운영에서도 등급이 기준이 됩니다. 로드 밸런서와 모니터링 도구는 응답을 등급별로 셉니다. 5xx 비율이 오르면 서버 쪽 장애로 보고 알림을 보냅니다. 4xx 가 오르면 클라이언트가 잘못 부르고 있다는 신호로 읽습니다.
그래서 서버 쪽 잘못을 4xx 로 보내면 장애가 알림에 안 잡힙니다. 반대로 사용자의 잘못된 입력을 5xx 로 보내면 멀쩡한 서버에 알림이 울립니다.
HTTP 밖의 등급
맨 앞 숫자로 결과를 묶는 방식은 HTTP 가 처음이 아닙니다. 메일을 나르는 SMTP(Simple Mail Transfer Protocol, 간이 메일 전송 프로토콜)와 파일을 주고받는 FTP(File Transfer Protocol, 파일 전송 프로토콜)도 결과를 세 자릿수 코드로 알리고 맨 앞 숫자로 나눕니다.
모양은 같아도 4 와 5 의 뜻은 다릅니다. 두 규약에서 4 는 다시 해 보면 될 수 있는 일시적인 실패입니다. 5 는 되풀이해도 소용없는 영구적인 실패입니다. HTTP 는 4 와 5 를 원인이 어느 쪽에 있는지로 가릅니다. 다른 규약의 코드를 HTTP 의 등급으로 읽으면 뜻이 어긋납니다.
관련 항목
등급으로 묶이는 상태 코드
상태 코드 · 100 Continue · 101 Switching Protocols · 200 OK · 201 Created · 204 No Content · 301 Moved Permanently · 302 Found · 304 Not Modified · 400 Bad Request · 401 Unauthorized · 404 Not Found · 429 Too Many Requests · 500 Internal Server Error · 502 Bad Gateway · 503 Service Unavailable
상태 코드 등급의 다섯 갈래
정보 응답 · 성공 응답 · 리다이렉션 · 클라이언트 오류 · 서버 오류
상태 코드와 함께 응답을 이루는 구성 요소
HTTP 응답 · 상태 줄 · 사유 구절 · 헤더 · Location 헤더 · 응답 본문
상태 코드 등급을 정의하는 규약과 문서
HTTP · HTTP-1.1 · HTTP-2 · RFC 9110
등급을 보고 다시 보낼지 정하는 기준
재시도 · 멱등성 · 지수 백오프 · Retry-After 헤더 · 타임아웃
등급을 읽고 동작을 바꾸는 중간 장치와 도구
클라이언트 · HTTP 클라이언트 · 프록시 · 캐시 · 로드 밸런서 · 모니터링 · 에러율
세 자릿수 코드를 맨 앞 숫자로 나누는 다른 프로토콜
상태 코드 등급을 고르는 설계 결정
다른 이름: status code class · 상태 코드 클래스 · 상태 코드 계열 · 상태 코드 범주 · 1xx · 2xx · 3xx · 4xx · 5xx