HTTP 통신의 응답 결과에는 Status Code가 포함됩니다.
해당 코드를 통해 결과가 어떠하다는 것을 요약적으로 할 수 있죠.
하지만 제가 만든 API들은 죄다 따로따로 개판인 것 같아서 어떻게 하는게 맞는지 좀 찾아봤습니다.

기초 정보

100단위로 묶음으로 비슷한 의미를 가진 것들이 묶여있습니다.
가령 5xx대는 서버측 에러, 4xx는 클라이언트측 에러입니다.
5xx 에러가 난다면 API 서버 개발자가 대응하면 되고, 4xx 에러가 나면 클라이언트 개발자가 대응해야겠죠.

5xx 시리즈 – Server Error

서버 내부 에러 – 500 Internal Server Error

보통 Production server를 실행했을때 에러가 발생하면 500이 발생합니다.
침착하게 서버 로그를 봅시다.

서비스 지원 불가 – 503 Service Unavailable

가령 웹 서버는 살아있지만 DB서버가 죽었다던가 하는 경우엔 정상적인 서비스 제공이 불가능합니다.
그런 경우에 발생시키면 좋습니다.

4xx 시리즈 – Client Error

요청이 이상해요 – 400 Bad Request

가령 생년월일 입력란에 2018-02-31 같은게 온 경우를 말합니다.
그 외에도 request body가 JSON이 예상되었는데 엉뚱한게 온 경우에도 400을 내보내면 됩니다.

다만, 요청이 Content-Negotiation에 실패한 경우라면 406 Not Acceptable을 고려해보세요.

해당 Method는 안 돼요 – 405 Method Not Allowed

가령 Read-only endpoint에 POST 등의 변경 요청이 온 경우에 내보내면 됩니다.

못 찾겠어요 – 404 Not Found

특정 요소를 특정한 요청이 왔는데 해당 리소스가 없다면 내보내면 됩니다.
가령 게시판에서 존재하지 않는 게시물을 요청한다던가 하는 경우를 예로 들 수 있겠네요.

다만, 리소스가 사라진게 아니라 사용할 수 없는 경우에는 410 Gone을 사용합니다.1

권한이 없어요 – 403 Forbidden

로그인을 하지 않은 경우, 로그인을 했지만 권한이 부족한 경우 등에 사용하면 됩니다.

다만, 로그인을 WWW-Authenticate header를 통해서 하는 경우인데 로그인이 안 된 경우라면 401 Unauthorized를 사용하세요.

요청 너무 많이 하셨어요 – 429 Too Many Requests

API에 rate limit 등이 있는데 요청이 제한량을 넘어버린 경우 사용합니다.
필수는 아니지만 Retry-After 헤더로 언제 이후로 다시 해보라던가 하는 힌트를 제공할 수 있습니다.

3xx 시리즈 – Redirection

이사갔어요 – 301 Moved Permanently

접속한 주소가 영영 다른 위치로 옮겨진 경우에 사용합니다.
Location 헤더로 다른 위치를 알려줘야 합니다.
브라우저에서도 새 위치를 기억하고, 검색엔진들도 새 위치로 URL을 변경합니다.

301의 경우 308 Permanent Redirect와 매우 흡사한데요, 301은 POST 요청이었어도 GET으로 바뀌지만2 308은 그러지 않습니다.

바뀐게 없어요 – 304 Not Modified

200을 받아간 뒤로 바뀐 부분이 없는데 또 요청이 온 경우에 반환합니다.
브라우저에서 Cache된 내용을 사용하게 됩니다.

잠깐만 여기로 가주세요 – 302 Found

완전히 옮겨가버린 301과 달리 302의 경우는 임시 이전입니다.
Location 헤더로 다른 위치를 알려줘야 합니다.

301과 308의 관계랑 유사하게 302에게는 307 Temporary Redirect가 존재합니다.
302는 POSTGET으로 바뀌지만 307은 그러지 않습니다.

2xx 시리즈 – Success

새로 만들었어요 – 201 Created

요청의 결과 새로운 리소스가 바로 만들어진 경우 사용합니다.
Location 헤더를 이용해서 만들어진 리소스의 URI를 포함해줘야 합니다.

요청을 해서 만들어지긴 만들어질건데 바로 만들어지지 않아서 좀 기다려야 하는 경우에는 202 Accepted를 사용해주세요.

괜찮아요 – 200 OK

HTTP의 기본값 같은 존재입니다.
요청의 문제가 없다면 대부분 200을 씁니다.

더 많이 있지 않나요?

이 글에서 다룬 HTTP Status Code는 매우 일부이고, 매우 간략한 설명만 담고 있습니다.
더 상세한 정보는 다음 사이트들을 참고해보세요.


  1. 리소스의 사용 가능 기한이 만료되었다던가
  2. 역사적인 이유라고 합니다. 하위 호환성 문제라고 보면 될 것 같습니다.