[새싹] 웹을 지탱하는 기술 Chapter08

채상엽·2022년 5월 10일
0

Sproutt 2nd - Spring Study

목록 보기
20/32

layout: post
title: "웹을 지탱하는 기술 스터디 - Chapter8"
date: 2022-04-08T00:00:00-00:00
author: sangyeop
categories: Sproutt-2nd


새싹 개발 서적 스터디 - 웹을 지탱하는 기술 Chapter08

Chapter 08. 스테이터스 코드

스테이터스 코드의 중요성

응답에 잘못된 스테이터스 코드를 할당하면 클라이언트가 혼동하여 시스템 전체 동작에 지장을 초래하기 때문에 스테이터스 코드를 바르게 이해하는 것이 중요하다.

스테이터스 라인의 복습

응답 메시지의 첫째 줄에 있는 스테이터스 라인은 프로토콜 버전, 스테이터스 코드, 텍스트 프레이즈로 이루어진다.

Http/1.1 200 OK

여기서 200이 스테이터스 코드가 된다. 텍스트 프레이즈는 사람이 읽을 수 있도록 표기한 것이기 때문에, 이외의 문구도 들어갈 수 있다.

스테이터스 코드의 분류와 의미

스테이터스 코드는 3자리 숫자이며, 첫째 자리 숫자에 따라 5가지로 분류된다.

status codedescription
1xx : 처리중처리가 계속되고 있음을 나타낸다. 클라이언트는 그대로 요청을 계속하던지 서버의 지시에 따라 프로토콜을 업데이트 하여 재전송한다.
2xx : 성공요청이 성공했음을 나타낸다
3xx : 리다이렉트다른 리소스로 리다이렉트를 나타낸다. 클라이언트는 이 스테이터스 코드를 받았을 때 응답메시지의 Location 헤더를 보고 새로운 리소스로 접속한다.
4xx : 클라이언트 에러클라이언트 에러를 나타낸다. 원인은 클라이언트의 요청에 있다. 에러를 해결하지 않는 한, 정상적인 결과를 얻을 수 없기 때문에 같은 요청을 그대로 재전송할 수는 없다.
5xx : 서버 에러서버 에러를 나타낸다. 원인이 서버에 있다. 서버 측의 원인이 해결되면, 동일한 요청을 재전송해서 정상적인 결과를 얻을 가능성이 있다.

이런식의 분류는 클라이언트와 서버 간의 약속을 최소한으로 억제하고 클라이언트와 서버의 결합을 가능한 한 완화하기 위해 고안된 것이다. 이를 소결합이라고 한다.

또한 추후에 새롭게 추가된 스테이터스 코드를 잘 알지 못하더라도 처음 숫자의 약속만 지켜진다면 최소한의 처리가 가능하기 때문에 매우 용이하다.

자주 사용되는 스테이터스 코드

200 OK - 요청 성공

요청이 성공했음을 나타낸다. GET의 경우에는 바디에 리소스의 표현이 들어간다.

  • GET 요청
GET /test HTTP/1.1
Host:example.com
  • GET 응답
HTTP/1.1 200 OK
Content-Type:text/plain; charset=utf-u8

Hello, World!

PUTPOST의 경우에는 바디에 처리 결과가 들어간다.

  • PUT요청
PUT /test HTTP/1.1
Host:example.com
Content-Type:text/plain; charset=utf-8

안녕하세요!
  • PUT응답
HTTP/1.1 200 OK
Content-Type:text/plain; charset=utf-8

안녕하세요!

201 Created - 리소스 작성 성공

리소스를 새로 작성했다는 것을 나타낸다. POSTPUT에 대한 응답으로서 반환된다.

POST의 경우, 새로 작성한 리소스 URI는 응답 메시지의 Location 헤더에 절대 URI로 들어간다.

  • POST요청
POST /list HTTP/1.1
Host:example.com
Content-Type:text/plain; charset=utf-8

안녕하세요!
  • POST응답
HTTP/1.1 201 Created
Location:http://example.com/list/item1
Content-Type:text/plain; charset=utf-8

안녕하세요!

PUT의 경우 클라이언트가 새로운 리소스 URI를 이미 알고 있으므로 Location 헤더는 들어가지 않는다.

  • PUT요청
PUT /newitem HTTP/1.1
Host:example.com
Content-Type:text/plain; charset=utf-8

안녕하세요!
  • PUT응답
HTTP/1.1 201 Created
Content-Type:text/plain; charset=utf-8

안녕하세요!

301 Moved Permanently - 리소스의 항구적인 이동

지정한 리소스를 새로운 URI로 이동했음을 나타낸다. 예전 URI를 유지하면서 새로운 URI로 이동할 때 이 코드를 사용한다.

다른 URI로 클라이언트가 자동적으로 재접속하는 처리를 리다이렉트라고 부른다.

303 See Other - 다른 URI의 참조

리다이렉트에 대한 처리결과를 다른 URI로 취득할 수 있음을 나타낸다. 보통 브라우저에서 POST로 리소스를 조작한 결과를 GET으로 가져올 때 사용한다.

  • POST 요청 - 리소스 조작
POST /login HTTP/1.1
Host:example.com 
Content-Type:application/x-www-form-urlencoded

username=yohei&password=foobar
  • 응답
HTTP/1.1 303 See Other
..
..
..

400 Bad Request - 요청 오류

요청 구문이나 파라미터가 잘못되었음을 나타낸다. 그 밖에 적절한 클라이언트 에러를 나타내는 코드가 없을 경우에도 사용 되며, 클라이언트가 모르는 4xx 계열 스테이터스 코드가 반환된 경우 400 Bad Request와 같은 처리를 하도록 규정이 되어있다.

401 Unauthorized - 접근 권한 없음, 인증 실패

적절한 인증정보를 부여하지 않은 채 리다이렉트를 수행했음을 나타낸다. 응답의 WWW-Authenticate헤더에서 클라이언트에 대해 인증방식을 전달한다.

  • 응답
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="example.com"

404 Not Found - 리소스 없음

지정한 리소스를 찾을 수 없음을 나타낸다. 응답 바디에는 그 이유가 들어간다.

  • 응답
HTTP/1.1 404 Not Found
Content-Type:text/plain; charset=utf-8

http://example.com/test를 찾을 수 없습니다.

500 Internal Server Error - 서버 내부 에러

서버 측에 무엇인가 이상이 발생해서 정상적인 응답을 보낼 수 없음을 나타낸다. 응답 바디에는 그 이유가 들어간다.

  • 응답
HTTP/1.1 500 Internal Server Error
Content-Type:text/plain; charset=utf-8

서버에 이상이 발생했습니다. 잠시 후 다시 접속해 주십시오.

다른 적절한 서버 에러를 나타내는 스테이터스 코드가 없을 경우, 클라이언트가 알지 못하는 5xx 계열이 반환된 경우 500 Internal Server Error와 같은 동작을 처리하도록 스펙으로 정해져 있다.

503 Service Unavailable - 서비스 정지

서버가 점검 등으로 일시적으로 액세스 할 수 없음을 나타낸다. 응답 바디에는 그 이유가 들어간다. Retry-After 헤더로 서비스 재개 시기가 대략 몇 십 초 후인지 통지 할 수 있다.

  • 응답
HTTP/1.1 503 Service Unavailable
Content-Type:text/plain; charset=utf-8
Retry-After:3600

지금은 점검 중입니다. 잠시 후 다시 접속해 주십시오.

스테이터스 코드와 에러처리

프로그램용 웹 API인 경우에는 클라이언트가 반드시 HTML을 해석할 수 있다고 단정할 수 없기 때문에, 웹 API는 클라이언트가 해석할 수 있는 형식으로 에러 메시지를 반환해 주어야 한다.

프로토콜에 따른 포맷으로 에러를 반환한다.

예를 들면 AtomPub클라이언트의 경우 Atom형식이라면 해석할 수 있기 때문에 AtomPub을 이용한 웹 API의 경우에는 에러 메시지는 Atom으로 반환하는 것이 한 방법이다.

Accpet 헤더에 따른 포맷으로 에러를 반환한다.

  • HTML 반환하는 경우
Accept: application/xhtml+xml:q=0.9, text/plain:q=0.3
  • Atom 반환하는 경우
Accept: application/atom+xml:q=0.9, text/plain:q=0.3

스테이터스 코드의 오용

웹 서비스의 경우에 404 Not Found로 반환해야할 정보를 200 OK로 반환하면 검색 엔진 로봇이 정식 리소스로 착각하고 인덱스 처리가 수행되어 버리는 등의 문제가 발생할 가능성이 있다.

스테이터스 코드를 의식해서 설계한다

스테이터스 코드 중에서 4xx에러는 다른 계열에 비해 코드의 종류가 많다. 이는 다양한 종류의 클라이언트 에러가 존재한다는 것을 의미한다.

스테이터스 코드는 스펙에 고정되어 있기 때문에 새로이 추가할 수 는 없다. 개발 중인 웹 서비스 웹 API에서 에러가 발생했을 때, 어떤 스테이터스 코드를 반환할지 결정하는 것은 아주 중요한 설계 검토사항이다.

스테이터스 코드의 구현

  • Apache

    정적인 파일을 보내는 경우, 보내는 파일의 조건에 따라 자동적으로 스테이터스 코드가 결정된다

  • 서블릿

    HttpServletResponse 클래스의 setStatus()setError() 메서드를 이용해 스테이터스 코드를 설정한다

  • Ruby on Rails

    컨트롤러에서 render메서드를 사용해 결과를 렌더링 할 때 인수로 스테이터스 코드 값을 전달한다.

profile
프로게이머 연습생 출신 주니어 서버 개발자 채상엽입니다.

0개의 댓글