티스토리 뷰

반응형

(1) 작업의 수행 상태를 알려주는 HTTP 상태 코드

클라이언트가 서버에게 작업을 요청하면 서버는 요청받은 작업을수행한 후 작업의 수행 결과를 응답으로 보내주는데, 이때 HTTP상태 코드를 사용하여 작업의 성공/실패 여부와 작업이 실패했다면 어떤이유로 실패했는지도 알려주게된다, HTTP 응답 바디에 작업의 실패 여부를 담아서 응답해주는 경우도 있지만, 더 좋은 방법은 바로 올바른 HTTP상태코드를 사용하는 것이다. 

HTTP 상태 코드는 200 = 성공,400 = 클라이언트가 요청 잘못함,500 = 서버가 잘못함  과 같이 각 상황에 맞는 코드가 표준으로 정해져 있으며,웹 상에서 돌아가는 기본적인 프로그램의 동작이나 프론트엔드, 백엔드 프레임워크들의 설계 또한 이 표준을 기준으로 만들어져 있기 때문에 되도록이면 이 표준을 지켜주는 것이 좋다. 

HTTP프로토콜을 사용하는 대표적인 프로그램인 웹 브라우저 또한 이러한 상태 코드 표준을 엄격하게 지키는 것 중하나인데, 실제로 브라우저는 서버가 어떤 상태 코드를 응답으로 내려주는지에 따라 이번에 자신이 보낸 요청의 성공/실패 여부를 구분하고, 이를 시각적으로 표현해주기도 한다.

(2) HTTP 상태 코드

100번대

100번대 코드는 프로토콜을 교체해도 된다거나 게속 요청을 보내도 된다거나 하는 식의 정보성을 띄고 있는 상태를 의미

200번대

200번대 코드들은 클라이언트가 요청한 작업을 서버가 성공적으로 수행했다는 상태라는 것을 알려주는 코드이다.

200 OK 상태 코드 200은 단순히 작업이 성공했음을 의미한다. 대부분의 경우 클라이언트는 자신이 요청한 작업이 정호가히 어떤 작업인지 알고 있기 때문에, 서버에서 "성공, 실패" 라는 정보만 알려주면 굳이 그 이상의 디테일한 정보는 알 필요가 없다. 그래서 이 상태코드 하나만으로 모든 API 응답 성공 상태를 퉁치는 경우가 대다수이다.

201 Created 상태 코드 200은 말 그대로 요청이 정상적으로 수행되었고, 그로 인해 리소스가 새롭게 생성되었다는 것을 의미한다. 클라이언트가 서버에게 요청을 보내서 새로운 리소스를 생성하는 상황은 굉장히 흔탄데, 그 중 가장 대표적인 사례는 바로 "회원가입"이다. 결국 클라이언트의 회원가입 요청으로 인해 데이터베이스에 새로운 유저의 로우가 생성되었기 때문에, 이런 경우가 201상태 코드가 아주 잘 들어맞는 케이스라고 볼 수 있다.

204 No Content 상태 코드 204는 요청이 정상적으로 수행되었고, 이 요청과 관련되었던 컨텐츠 또한 더 이상 깔끔하게 존재하지 않음을 의미한다. 이 상태 코드는 클라이언트가 서버에게 요청을 보내서 뭔가를 삭제해야하는 응답으로 사용될 수 있다. 

참고로 이때 이 삭제 작업이 Soft Delete Hard Delete냐와는 아무런 상관이 없다. 서버에서 어떤 방식으로 리소스의 삭제를 표현하던 클라이언트가 알아야할 정보는 "이 리소스는 삭제되었고, 더 이상 사용할 수 없다"뿐이라는 사실을 명심하자.

300번대

300번대 코드들은 리다이렉션에 관련된 상태들을 의미한다. 클라이언트가 요청한 리소스가 옮겨졌거나 리소스가 삭제되었거나해서 정상적인 방법으로는 더이상 해당 리소스에 접근할 수 없고 다른 URL을 통해서 그 리소스에 접근해야하는 경우 서버는 어디에 해당 리소스가 있는지에대한 정보를 알려줄수 있는데, 이 때 사용되는 상태 코드 들이 바로 300번대 코드들이다. 

301 Moved Permanetly 상태 코드 301은 301 Redirect라는 별칭으로 불리기도 할 만큼 리다이렉션을 위한 코드 중 가장 많이 사용된다. 브라우저는 자신에 대한 요청의 응답으로 301을 받으면 HTTP헤더에 들어있는 location 필드를 찾아보고, 해당 필드가 존재할 경우 Location 필드에 담긴 URL로 자동으로 리다이렉션한다.

HTTP/1.1 301 Moved Permanetly
Location: https://evan/moved-contents/1234

또한 구글과 같은 검색 엔진의 봇들은 특정 페이지에 접근했는데 응답으로 301상태 코드를 받을 경우 자동으로 페이지 정보를 갱신하기도 하기 때문에, SE)관점에서도 이 상태 코드를 올바르게 사용하는 것은 매우 중요하다.

이런 리다이렉션 설정은 보통 서버 엔진의 설정 파일 내에서도 할 수 있고, 백엔드 어플리케이션 내에서 직접 할 수도 있다. 일반적인 경우 이 상태코드는 HTTP 프로토콜로 접속한 사용자를 HTTPS 프로토콜을 사용해야만 접근 가능한 포트로 보낼 때에도 많이 사용된다.

304 Not Modified 상태 코드 304는 클라이언트가 요청한 리소스가 이전 요청때와 비교해보았을 때 전혀 달라진 점이 없다는 것을 의미한다. 즉 말 그대로 Not Modified, 수정되지 않음이다. 

서버가 응답으로 이 상태 코드를 보내주면 클라이언트는 굳이 서버에게 리소스를 재전송받아야할 필요가 없기에 자신이 캐싱해놓았던 리소스를 사용하게되며, 이 과정에서 불필요한 통신 페이로드의 낭비를 줄일 수 있다.

301 Moved Permanetly 상태 코드 301 301 Redirect라는 별칭으로 불리기도 할 만큼 리다이렉션을 위한 코드 중 가장 많이 사용되는 녀석이다. 브라우저는 자신의 대한 요청의 응답으로 301을 받으면 HTTP 헤더에 들어있는 Location 필드를 찾아보고, 해당 필드가 존재할 경우 Location 필드에 담긴 URL로 자동으로 리다이렉션한다.

304 Not Modified 상태 코드 304는 클라이언트가 요청한 리소스가 이전 요청때와 비교해보았을 때 전혀 달라진 점이 없다는 것을 의미한다. 즉, 말 그대로 Not Modified, 수정되지 않음이다.

400번대

400번대의 코드들은 클라이언트가 서버에게 보낸 요청이 잘못된 경우를 의미한다. 만약 이 상태 코드를 발견한다면 높은 확률로 프론트엔드 개발자가 예외 처리를 제대로 안 했거나 요청에 이상한 값이 묻은 경우가 많다.

400 Bad Request 상태 코드 400는 가장 많이 만날 수 있는 400번대 코드 중 하나이다

401 Unauthorized 상태 코드 401는 인증되지 않은 사용자가 인증이 필요한 리소스를 요청하는 경우에 “너 인증 필요함”이라고 알려주는 상태 코드이다. 보통 로그인이 필요한 API를 비로그인 사용자가 호출했을 때 많이 사용된다.

클라이언트에서는 서버가 401을 응답으로 보내준 경우, 로그인이 필요하다는 것으로 판단하고 로그인 페이지로 사용자를 리다이렉션하기도 한다.

403 Forbidden 상태 코드 403는 클라이언트가 접근이 금지된 리소스를 요청했음을 의미한다. 이 상태 코드는 간혹 401 Unauthorized와 헷갈리고는 하는데, 상태 코드의 의미만 보면 확실히 애매모호하지만, 사실 분명한 한 가지 차이점이 있다.

401은 말 그대로 인증되지 않았다는 것을 의미하며, 인증이 되지 않았다는 것은 백엔드 어플리케이션이 현재 요청한 사용자가 누구인지 알 수가 없다는 것을 의미한다. 즉 이때 서버는 클라이언트에게 “너의 신원을 밝혀!”라고 말하고 있는 것이다.

그러나 403의 경우, 백엔드 어플리케이션은 현재 리소스를 요청한 사용자가 누구인지 전혀 신경쓰지 않는다. 클라이언트가 현재 자신이 누구인지 밝혔던 밝히지 않았던, 인증이 되었던 안 되었던 간에, 이 리소스를 요청하는 것은 무조건 금지라고 말하고 있는 것이다.

HTTPS 프로토콜로만 접근해야하는 리소스에 HTTP 프로토콜을 사용하여 접근했을 경우에 서버에서 403 응답을 보내주기도 한다.

404 Not Found 상태 코드 404는 말 그대로 요청한 리소스가 존재하지 않다는 것을 의미한다.

405 Method Not Allowed 상태 코드 405는 현재 리소스에 맞지않는 메소드를 사용했음을 의미한다. 백엔드 프레임워크의 경우 특정 컨트롤러에 해당 메소드를 사용하는 로직이 없다면 자동으로 405를 내려주기도 한다.

406 No Acceptable 상태 코드 406은 서버 주도 컨텐츠 협상을 진행했음에도 불구하고 알맞은 컨텐츠 타입이 없다는 것을 의미한다.

사실 클라이언트는 서버에게 리소스를 요청할 때, HTTP 헤더의 Accept 필드를 사용하여 어떤 컨텐츠 타입의 리소스를 원하는지도 함께 이야기해준다. 일반적으로 이 필드를 명시하지않을 경우 브라우저는 자동으로 text/html을 비롯한 몇 가지 타입들을 스스로 정의해서 헤더에 담아주고는 한다.

GET http://evan.com/
Accept: text/html,application/xhtml+xml,application/xml,*/*
...

이런 요청을 받은 서버는 클라이언트가 보낸 요청의 Accept 필드를 보고 앞에서부터 하나씩 찾아가며 요청받은 리소스와 알맞은 컨텐츠 타입이 있는지 하나씩 살펴보게 되고, 이후 알맞은 컨텐츠 타입이 있다면 HTTP 응답 헤더의 Content-Type 필드에 해당 컨텐츠 타입을 명시해주게 된다.

HTTP/1.1 200 OK
Content-Type: text/html

이 과정에서 어떤 컨텐츠 타입의 리소스를 응답으로 내려줄 것인지는 전적으로 서버가 결정하게 되므로 이 과정을 “서버 주도 컨텐츠 협상”이라고 하는 것이다. 위의 예시의 경우 클라이언트가 받기를 원했던 컨텐츠 타입 중 첫 번째 우선순위를 가진 text/html를 받아왔지만, 만약 서버에 text/html 타입의 리소스가 존재하지 않는 경우, 서버는 application/xhtml+xml, application/xml 순서로 리소스를 탐색하게 된다.

만약 앞에 나열된 모든 컨텐츠 타입이 없는 경우 클라이언트가 요청했던 컨텐츠 타입 중 가장 마지막인 */* 와일드 카드에 걸리기 때문에, 서버는 리소스가 어떤 컨텐츠 타입인지 상관하지 않고 그대로 응답해줄 것이다. 그러나 만약 클라이언트가 요청한 컨텐츠 타입을 모두 탐색했는데도 불구하고 알맞은 리소스가 없을 경우 서버는 406 상태 코드와 함께 “니가 찾는 컨텐츠 타입과 맞는 리소스가 없어”라는 응답을 주는 것이다.

408 Request Timeout 상태 코드 408은 클라이언트와 서버의 연결은 성사되었지만 요청의 본문이 계속 서버에 도착하지 않는 상황을 의미한다.

HTTP 프로토콜을 사용하여 통신을 할 때는 반드시 클라이언트와 서버 간의 연결을 생성하고, 그 이후에 요청 본문에 해당하는 데이터를 전송하게 되는데, 408 상태 코드는 이 과정에서 연결은 제대로 생성되었지만 서버가 아무리 기다려도 클라이언트가 보냈던 요청 본문을 받지 못하는 경우에 발생하게 된다.

429 Too Many Requests 상태 코드 429는 클라이언트가 서버에 너무 요청을 많이 보내는 경우에 발생한다. 너무 많이 보냈다는 것은, 너무 짧은 시간 안에 빠르게 요청을 마구 날려대서 서버가 “워워 진정해”라고 하는 경우일수도 있고, 유료 API를 사용하는 경우에는 현재 금액으로 사용할 수 있는 API 요청 횟수를 초과해서 “돈을 더 내세요”라는 의미로 사용되기도 한다.

서버에서는 429 상태 코드와 함께 응답 헤더의 Retry-After라는 필드를 사용하여 “이 시간 이후에 재요청해봐”라는 의미를 전달할 수도 있다.

500번대

500번대의 코드들은 클라이언트가 아닌 서버에서 뭔가 말썽이 일어난 경우이다. 만약 이 상태 코드를 발견했다면 서버에서 뭔가 박살났다는 의미이므로 다소곳이 백엔드 개발자의 멱살을 잡아보도록 하자.

500 Internal Server Error 상태 코드 500은 백엔드 어플리케이션 내에서 뭔가 알 수 없는 에러가 발생했다는 의미이다. 대부분 제대로 핸들링되지 않은 에러가 발생한 경우가 많으므로, 에러의 원인을 클라이언트에게 알려주지 않는다.(라기 보다 알려줄 수 없는 상태인 경우가 많다)

또한 이렇게 핸들링되지 않은 에러의 원인을 클라이언트에게 고스란히 알려주는 것은 보안 사고가 발생할 가능성이 너무 크므로, 500 상태 코드로 에러의 발생 자체만을 알려주는 경우가 대부분이다. 만약 이 상태 코드를 만난다면, 바로 서버 로그를 까보거나 Sentry Bugsnag과 같은 에러 모니터링 솔루션을 적극 활용하는 것을 추천한다.

502 Bad Gateway 상태 코드 502를 만날 수 있는 가장 흔한 상황은 바로 백엔드 어플리케이션이 죽은 상황이다. 근데 왜 Server Died와 같이 직접적인 메세지가 아니라 Bad Gateway와 같은 메세지를 보내주는 것일까?

그 이유는 백엔드 아키텍처가 아무리 간단한 구조라고 해도 절대 어플리케이션 1개로만 구성되지 않기 때문이다. 여기서 말하는 게이트웨이는 어플리케이션 간의 추상적인 연결점을 의미하는데, 이 메세지가 의미하듯 백엔드의 아키텍처는 최소 2개 이상의 어플리케이션으로 구성된 경우가 대부분이다.server { listen 80; server_name evan.com; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }

503 Service Unavailable 상태 코드 503은 서버가 요청을 처리할 준비가 되지 않았음을 의미한다. 간혹 502 Bad Gateway와 비슷한 느낌으로 사용되기는 하지만, 503은 보다 “일시적인 상황”을 의미하는 상태 코드이며, 일반적으로 서버에 부하가 심해서 현재 요청을 핸들링 할 수 있는 여유가 없는 경우에 많이 사용된다.

AWS Lambda에서는 요청을 처리할 때 컨테이너의 동시 실행 갯수를 초과할 정도의 리소스가 필요하거나 어떤 작업의 처리 시간이 Lambda에 설정된 컨테이너의 최대 수명 시간을 초과했을 경우에 발생하기도 한다.

이렇듯이 503은 일시적인 상황을 의미하므로 429 Too Many Requests와 동일하게 응답 헤더의 Retry-After 필드를 사용하여 “이 시간 이후에 다시 요청해봐”라는 의미를 클라이언트에게 전달해줄 수 있다.

504 Gateway Timeout 상태 코드 504는 408과 마찬가지로 요청에 대한 타임아웃을 의미한다. 그러나 504 상태 코드는 클라이언트에서 보낸 요청 때문에 타임아웃이 발생하는 것이 아니라 백엔드 아키텍처 내부에서 서버끼리 주고받는 요청에서 발생한다.

앞서 이야기했듯이 백엔드의 아키텍처는 단순히 백엔드 어플리케이션 하나로만 구성된 것이 아니기 때문에, 클라이언트의 요청이 서버에 닿은 뒤에도 백엔드 어플리케이션끼리의 통신이 발생하게 된다. 만약 프록시 서버 역할을 맡은 Nginx가 백엔드 어플리케이션에 클라이언트의 요청을 전달했는데, 백엔드 어플리케이션이 일정 시간 동안 응답을 하지 않는 경우 Nginx는 클라이언트에게 504 Geteway Timeout을 내려주게 되는 것이다.

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함