REST API 관점에서 바라보는 HTTP 상태 코드(HTTP status code)

Error Coder·2023년 2월 8일
0

코딩을 진행하다 보면 빈번하게 에러와 마주칠 수 있다.

상태 코드를 정확히 모르는 것 같아 자세하게 알아보려고 한다.

HTTP와 REST

HTTP(HyperText Transfer Protocol)는 웹 환경에서 정보를 주고받기 위한 프로토콜이다.

클라이언트는 HTTP의 상태 코드를 확인하여 요청의 성공,실패를 확인할 수 있다.

이것은 HTTP를 사용하는 클라이언트와 서버 간의 약속, 프로토콜인 것이다.

REST(Representational State Transfer)는 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처이다.

HTTP는 웹 환경에서 정보를 송수신할 때 사용하는 약속이고, REST는 소프트웨어 아키텍처다.

REST에 반드시 HTTP가 필요한 것은 아니다. WAP, WebRTC, MQTT 등 다른 프로토콜로도 이용 가능하다.

REST는 소프트웨어 아키텍처(설계 지침, 원리 등등)고 REST에서 클라이언트-서버 간 통신 시 HTTP를 사용한 것이다.

HTTP Status Code (상태 코드)

HTTP Status code, 상태 코드는 HTTP 요청이 성공했는지 실패했는지를 서버에서 알려주는 코드다.

2XX Success

2xx 번대의 상태 코드들은 서버가 클라이언트의 요청을 성공적으로 처리했다는 의미다.

200 OK
클라이언트의 요청을 서버가 정상적으로 처리했다.

성공에 대한 모든 상태 코드를 200으로 응답해도 크게 상관없다. (200 상태 코드는 클라이언트에게 요청이 성공했다는 것을 응답하는 기능을 갖기 때문에)
많은 REST API에서 2xx 상태 코드를 세분화하여 사용하지 않는다.

201 Created
클라이언트의 요청을 서버가 정상적으로 처리했고 새로운 리소스가 생겼다.

201 상태 코드는 POST, PUT 요청에 대한 응답에 주로 사용된다.
클라이언트의 요청이 성공적으로 이뤄졌다는 의미까지는 200과 동일한데, 성공과 동시에 새로운 리소스가 생성되었다는 의미를 포함한다

202 Accepted
클라이언트의 요청은 정상적이나, 서버가 아직 요청을 완료하지 못했다.

202 상태 코드는 비동기에 대한 개념이 없다면 생소할 수 있다.
클라이언트의 요청이 정상적이면 서버에선 작업의 성공|실패 응답하는 게 일반적이나, 작업 완료를 위한 일련의 작업들이 오래 걸리기 때문에 나중에 알려주겠다는 의미다.

202 상태 코드에서 중요한 것은 작업의 확인이다. 비동기 작업은 해당 요청이 언제 완료되는지 알 수 없다.
클라이언트가 요청의 완료 여부를 확인할 수 있는 방법을 제공해야 한다. 2가지 방법이 있다.

Callback

Polling

콜백은 서버가 작업이 완료되면 클라이언트에게 알려주는 것이다.
폴링은 클라이언트가 주기적으로 해당 작업의 상태를 조회하는 것이다.(HATEOAS, Content-Location 등으로 작업의 상태를 확인할 수 있는 URI를 응답해야 한다.)
콜백과 폴링에 대한 이야기는 길어질 수 있기 때문에 위에 설명한 개념 정도만 알고 넘어간다.

204 No Content
클라이언트의 요청은 정상적이다. 하지만 컨텐츠를 제공하지 않는다.

202 상태 코드와 유사하게 이상한 응답이라 생각할 수 있다. 자원을 제공하지 않는 경우가 뭘까?
204 상태 코드는 자원의 삭제 요청에 응답할 수 있다.

4XX Client errors

4XX의 상태 코드들은 클라이언트의 요청이 유효하지 않아 서버가 해당 요청을 수행하지 않았다는 의미다.

400 Bad Request
클라이언트의 요청이 유효하지 않아 더 이상 작업을 진행하지 않는 경우

API 서버는 클라이언트 요청이 들어오면 바로 작업을 진행하지 않고 요청이 서버가 정의한 유효성에 맞는지 확인 후 진행한다.
다음과 같은 사전 유효성 검증 작업을 진행할 수 있다.

필수 여부

유효 여부

범위

패턴

대부분의 API는 사전에 유효성 검증을 통해 400 상태 코드로 클라이언트에게 유효하지 않은 요청임을 응답한다.
(유효성 검증 없이 진행하면 5xx 서버 오류가 발생할 수 있기 때문에 대부분 사전에 막는 로직을 추가한다.)

그러나, 400 상태 코드로 응답하는 것만으로는 부족하다.
오류 발생 시 파라미터의 위치(path, query, body), 사용자 입력 값, 에러 이유를 꼭 명시하는 것이 좋다.

401 Unauthorized
클라이언트가 권한이 없기 때문에 작업을 진행할 수 없는 경우

un-authorized
un
authorized: 인정받은, 권한을 부여받은

상태 코드 이름만 보면 권한(authorized)에 대한 내용처럼 보이지만, 사실 인증(authenticated)에 대한 이야기다.

401은 비인증이다.

403 Forbidden
클라이언트가 권한이 없기 때문에 작업을 진행할 수 없는 경우

403은 권한(authorized)에 대한 내용이다.
401의 상태 코드명이 Unauthorized라 혼동의 여지가 있으나, 권한에 대한 내용이다.
인증된 클라이언트가 권한이 없는 자원에 접근할 때 응답하는 상태 코드다.

404 Not Found
클라이언트가 요청한 자원이 존재하지 않다.

브라우저(클라이언트) 입장에선 자원이 웹 페이지 경로고 존재하지 않는 경로(자원)를 요청했기 때문에 404 상태 코드를 응답했다.

REST API에선 크게 두 가지 경우에서 404 상태 코드를 응답한다.

경로가 존재하지 않음

자원이 존재하지 않음

405 Method Not Allowed
클라이언트의 요청이 허용되지 않는 메소드인 경우

메소드란 POST, GET, PUT, DELTE 등 HTTP Method를 말한다.
즉, 자원(URI)은 존재하지만 해당 자원이 지원하지 않는 메소드일 때 응답하는 상태 코드다.

405 상태 코드는 OPTIONS 메소드와 HTTP header의 Allow와 연관되어있다.

OPTIONS는 API가 허용하는 메소드가 어떤 것들이 있는지 확인하는 메소드다.
405오류를 사전에 방지하기 위한 용도에 주로 쓰인다.
이 때 응답 HTTP header의 Allow에 지원하는 메소드를 나열하여 응답한다.

RESTful API 설계 가이드에서도 말한 내용이지만 완성도 높은 API를 위해 제공하길 추천한
다.(최근 몇몇 API 프레임워크에선 자동으로 허용되지 않는 메소드에 대해 405 상태 코드와 Allow 헤더를 응답하기도 한다.)

409 Conflict
클라이언트의 요청이 서버의 상태와 충돌이 발생한 경우

충돌이라는 것은 매우 추상적이다. 앞에서 알아본 400, 401, 403, 404, 405 상태 코드들은 사용이 꽤 명확하다.
하지만, 충돌이라는 것은 정의하기 나름이다.
그렇기 때문에 필자는 400, 401, 403, 404, 405 상태 코드에 속하기 애매한 오류의 상황들을 409로 응답한다.

429 Too Many Requests
클라이언트가 일정 시간 동안 너무 많은 요청을 보낸 경우

비정상적인(DoS attack, Brute-force attack) 방법으로 자원을 요청하는 경우 응답한다.

DoS는 가용성에 대한 공격이고 Brute-force는 기밀성에 대한 공격이다. 하지만, 서버 입장에서 두 공격 모두 가용성에 피해를 입을 수 있다.
서버가 감당하기 힘든 요청이 지속적으로 들어오면 서버는 해당 요청을 처리하기 위해 다른 작업을 처리하지 못할 수 있다.

429 상태 코드는 이러한 경우 일정 시간 뒤 요청할 것을 나타내는 것이다. 따라서 다음과 같이 HTTP hearder Retry-After을 이용한다.

5XX Server errors
5XX 상태 코드들은 서버 오류로 인해 요청을 수행할 수 없다는 의미다.

클라이언트의 요청은 유효하여 작업을 진행했는데 도중에 오류가 발생한 경우다.

404 오류와 마찬가지로 인터넷을 하다 보면 500, 502, 503 등의 오류를 만나봤을 거다.

API 서버의 응답에서 5XX오류가 발생해서는 안된다.
보통 개발 과정에서 유효하지 않은 요청을 사전에 처리하지 않은 경우(400)에 많이 발생한다.

API를 사용하는 클라이언트에게 5XX 상태 코드는 나타내지 말아야 한다!

최신의 웹 애플리케이션 프레임워크는 자체 웹서버를 내장하고 있어서 웹서버(Apache, Nginx) 없이 운영할 수 있다.

그러나, 보통 운영 레벨에서 이렇게 하는 경우는 드물고 앞에 웹서버를 두고 웹 애플리케이션을 연결해서 운영한다.

따라서, 상단의 웹서버(Apache, Nginx)에서 발생하는 어쩔 수 없는 오류를 제외하고 API에선 5XX 상태 코드가 응답되선 안된다.

API 레벨에선 완벽한 예외처리를 통해 5XX 서버 오류 상태 코드를 방지해야 한다.

출처 : https://sanghaklee.tistory.com/61

profile
개발자 지망생

0개의 댓글