최근에 REST api 에 대해서 공부했었는데, 마침 새로운 기능을 만들 일이 있어서 해당 기능에 REST 를 적용해서 만드려고 하고 있습니다. 그런데 이전 코드에서는 HTTP 메소드를 GET,POST 구분없이 사용하고 있었기에 (조회를 할 때, POST 에 파라미터를 사용해서 한다거나 하는 형식), 클라이언트 개발자분이랑 맞추면서 하는데, 서로 기본적이라고 생각하는 부분이 다르기에 이해시켜주는데 에를 먹었던 기억이 있습니다. (헤더의 Content-Type 이라던가, Accept-Type 등)
얘기를 하면서, 내가 어느 정도 알아도, 설명을 하는 것은 또 별개의 영역이라는 느낌이 들더군요. (물론 잘 알면, 설명도 잘 하겠지만요..)
막연하게 당연히 그런거 아니야? 라고 생각할 만한 HTTP 헤더와 상태 코드에 대해서 정리해보는 시간을 가져볼까 합니다.
1. HTTP 메시지의 흐름
HTTP 메시지는 서버와 클라이언트 간에 주고받는 데이터의 흐름이라고 할 수 있습니다.
보통 여기서 많은 들어본, 인바운드와 아웃바운드라는 말이 나오는데요.
서버 방향(클라이언트 -> 서버) 을 인 바운드 라고 하고, 클라이언트 방향(서버 -> 클라이언트) 을 아웃 바운드라고 합니다.
그리고 메시지는 항상 다운스트림으로 흐릅니다.
여기서 왜 항상 다운스트림인가 하면, 이건 메시지가 어딜 향하는가에 대한 내용이 아닌 발송자와 수신자의 대한 내용이기 때문입니다. (클라 -> 서버, 서버 -> 클라)
HTTP 메시지는 주로 시작줄, 헤더, 본문 이렇게 3개로 구성되어 있으며, 본문은 필수가 아닙니다.
주로 요청에서는
GET /hello HTTP/1.1 - 시작줄
------
Accept: text/plain - 헤더
Host : ysjune.github.io
그리고 이에 대한 응답에서는
HTTP /1.1 200 OK. - 시작줄
------
Content-type : text/plain. - 헤더
Content-length : 20
------
Hi! Long time no see! - 본문
이런식으로 구성되어 있습니다.
각 줄에 대한 내용을 간략하게 보면,
- 요청
- 시작줄
- 메소드로 시작하며, 서버에게 무엇을 해야 하는지 말해줍니다.
- URL 과 함께 HTTP 버전을 함께 보내줍니다.
- 헤더
- 요청에 추가 정보를 더합니다.
- 위의 예에서
Accept: text/plain
는 클라이언트는 text 를 받을 수 있다는 얘기입니다.
- 시작줄
- 응답
- 시작줄
- 클라이언트에게 무엇이 일어났는지 알려줍니다.
- 위의 예
HTTP /1.1 200 OK
에서 상태코드는 200 입니다.
- 헤더
- 응답 메시지에 추가 정보를 더합니다.
- 위의 예에서 본문은 text 이고, 길이는 20 이라는 것을 알 수 있습니다.
- 본문
- 선택적인 것으로 본문은 주지 않는 응답도 있습니다.
- 시작줄
2. HTTP 메소드
대략적인 메시지의 흐름을 봤습니다.
이번엔 시작줄에 위치한 HTTP 메소드(GET, POST 등) 에 대해 알아보겠습니다.
1. GET
- 주로 서버에서 리소스를 요청할 때 쓰이며, 가장 흔히 쓰이는 메소드입니다.
- 주로 멱등성 (몇 번을 호출하든 같은 내용) 에 대한 내용이 나올 때 많이 나오는 메소드 입니다.
2. HEAD
- GET 과 같이 행동하지만, 서버는 응답으로 헤더만을 돌려줍니다.
- 본문이 없기 때문에, 주로 상태가 존재하거나, 변경되었는지를 확인하는 용도로 사용합니다.
3. PUT
- 서버가 요청을 본문을 가지고 요청 URL 의 이름대로 새 문서를 만들거나, 본문을 교체하는 것입니다.
- PUT 으로 콘텐츠를 변경할 수 있기 때문에, 선행작업으로 로그인등을 요구하는 경우가 많습니다.
4. POST
- 서버에 입력 데이터를 전송하기 위해 설계되었습니다.
- PUT 과 겹치는 내용이 많지만, 주로 새 문서를 만들 때 사용합니다.
5. TRACE
- 클라이언트가 어떤 요청을 할 때, 그 요청은 방화벽, 프록시, 게이트웨이 등을 통과할 수 있는데, 이런 요청을 통과할 때 데이터가 변경될 수 있습니다. (ex. 헤더 내용 추가 등) 이럴 때, 자신의 요청이 서버에 도달했을 때, 어떻게 보이는 지를 확인할 수 있습니다.
6. OPTIONS
- 웹 서버에게 어떤 메소드가 지원되는지 물어봅니다.
7. DELETE
- 서버에서 요청 URL로 지정한 리소스를 삭제할 것을 요청합니다.
- 하지만, 요청이 확실히 삭제되었는지는 보장하지 않습니다. HTTP 명세에서는 서버가 클라이언트에게 알리지 않고 요청을 무시하는 것을 허용하기 때문입니다.
위의 내용들을 간략하게 표로 보면
메소드 | 설명 | 본문 포함 여부 |
---|---|---|
GET | 서버에서 리소스를 가져온다. | X |
HEAD | 서버에서 리소스의 헤더만 가져온다. | X |
POST | 서버가 처리할 데이터를 보낸다. (주로 생성) | O |
PUT | 서버에 요청 메시지의 본문을 저장한다. | O |
TRACE | 메시지가 서버에 도달하는 과정을 추적 | X |
OPTIONS | 서버가 어떤 메시지를 수행할 수 있는지 확인 | X |
DELETE | 서버에서 리소스를 제거한다. | X |
3. 상태 코드
응답을 할 때 보내주는 상태코드로, 100번대 부터 500번대까지 크게 5가지로 나뉩니다.
1. 100번대 상태코드 : 정보성 상태코드
- HTTP/1.1 에서 도입되었으며, 복잡한 형태를 띄고 있습니다.
상태 코드 | 내용 | 의미 |
---|---|---|
100 | Continue | 요청의 시작 부분 일부가 받아들여졌으며, 클라이언트는 나머지를 계속 이어서 보내야 함을 의미합니다. |
2. 200번대 상태코드 : 성공 상태코드
- 클라이언트가 요청을 보내면, 대게 성공하는데 서버는 그에 대응하는 상태코드를 가지고 있습니다.
상태코드 | 내용 | 의미 |
---|---|---|
200 | OK | 정상 요청 |
201 | Created | 서버 개체를 생성하는 요청에 대한 응답 |
202 | Accepted | 요청은 받아들여졌으나, 그에 대한 동작은 수행하지 않았다. |
203 | Non-Authoritative Information | 엔터디 헤더에 들어가있는 정보가 원래 서버가 아닌 리소스의 사본에서 왔음 |
204 | No Content | 응답 메시지는 헤더와 상태를 포함하지만, 본문은 포함하지 않을 경우 |
205 | Reset Content | 브라우저에서 현재 페이지에 있는 HTML 폼 값을 리셋 |
206 | Partial Content | 부분 혹은 범위 요청이 성공 |
3. 300번대 상태코드 : 리다이렉션 상태코드
- 클라이언트가 관심있어 하는 리소스에 대해 다른 위치를 사용하라고 말해주거나, 다른 대안 응답을 제공합니다.
상태코드 | 내용 | 의미 |
---|---|---|
300 | Multiple Choice | 클라이언트가 동시에 여러 리소스를 가리키는 URL 을 요청한 경우, 그 리소스의 목록과 함께 반환 |
301 | Moved Permanently | 요청한 URL 이 옮겨졌을 때 사용 |
305 | Use Proxy | 리소스가 반드시 프록시를 통해서 접근되어야 함을 나타냄 |
4. 400번대 상태코드 : 클라이언트 에러 상태코드
- 서버가 다룰 수 없는 무언가를 보낼 때 나오는 응답코드 입니다.
상태코드 | 내용 | 의미 |
---|---|---|
400 | Bad Request | 클라이언트가 잘못된 요청을 보냈을 경우 |
401 | Unauthorized | 리소스를 얻기 전에 클라이언트에게 스스로 인증을 하라고 요구 |
403 | Forbidden | 요청에 서버에 의해 거부되었음 (보통 서버가 거절의 이유를 숨기고 싶을 때 사용) |
404 | Not Found | 요청한 URL 을 찾을 수 없음 |
405 | Method Not Allowed | 요청한 URL 에 대해 지원하지 않는 메소드로 요청했을 때 사용 |
406 | Not Acceptable | 주어진 URL 에 대해 응답을 할 때, 클라이언트가 받을 수 없는 리소스를 사용하는 경우 |
408 | Request Timeout | 클라이언트의 요청을 완수하기에 시간이 너무 많이 걸리는 경우 |
415 | Unsupported Media Type | 서버가 이해하거나 지원하지 못하는 내용 유형의 엔티티를 클라이언트가 보냈을 때 사용 |
5. 500번대 상태코드 : 서버 에러 상태코드
- 클라이언트가 올바른 요청을 보냈음에도 서버 자체에서 에러가 발생하는 경우 사용합니다.
상태코드 | 내용 | 의미 |
---|---|---|
500 | Internal Server Error | 서버가 요청을 처리할 수 없게 만드는 에러는 만났을 때 사용 |
502 | Bad Gateway | 프록시나 게이트웨이로부터 요청을 못 보내거나 응답을 못 받을 때 (ex, 부모 게이트웨이 접속 불가) |
503 | Service Unavailable | 서버가 요청을 처리할 수는 있으나, 현재는 불가능하고 나중에 가능할 때 사용 |
504 | Gateway Timeout | 408 상태코드와 비슷하지만, 다른 서버나 게이트웨이로부터 응답을 받다가 타임아웃이 발생한 경우 |
4. 헤더
헤더는 메소드와 함께 클라이언트와 서버가 무엇을 하는지 결정하기 위해 함께 사용됩니다.
헤더는 크게 다섯 가지로 분류됩니다.
1. 일반 헤더
- 클라이언트와 서버 양쪽 모두가 사용합니다.
ex) 메시지가 만들어진 일시를 지칭하기 위해 사용할 경우
Date: Sat, 17 Apr 2021 02:02:22 GMT
2. 요청 헤더
요청 메시지를 위한 헤더입니다.
서버에게 클라이언트가 받고자 하는 데이터의 타입이 무엇인지 같은 정보가 있습니다.
ex) 서버로부터 어떤 미디어 타입도 받아들일 경우
Accept : * / *
3. 응답 헤더
- 클라이언트에게 부가 정보를 제공할 때 사용하는 헤더입니다.
ex) 서버 어플리케이션의 이름
Server : toy Server
ex) 현재 리소스가 불가능할 때 언제 가능해지는지 시각 혹은 날짜 제공
Retry-After : Sat, 17 Apr 2021 02:02:22 GMT
4. 엔티티 헤더
- 본문에 대한 헤더를 말합니다.
ex) 본문에 들어있는 데이터가 UTF-8 인 경우
Content-Type : text/html; charset=utf-8
ex) 본문의 길이가 20 인 경우
Content-Length : 20
5. 확장 헤더
- 개발자들에 의해 만들어졌지만, 아직 승인되진 않은 비표준 헤더입니다.
- HTTP 프로그램은 확장 헤더들에 대해 설령 의미를 모른다할지라도 전달해야 합니다.
5. 정리
HTTP 메시지에 대해서 쭉 정리를 해봤는데,
아는 내용도 있었지만, 몰랐거나 처음보는 내용도 있었습니다. (특히 상태코드 부분)
현업을 하고 있음에도, 다른 곳에서는 얼마나 상태코드를 유연하게 쓰고 있는지는 잘 모르겠네요. (REST를 얼마나 잘 지켜가면서 개발하고 있는 것과 같은 맥락일려나요?)
회사의 컨벤션에 맞게 개발하면서도, 이런 내용들은 알고 잘못 쓰는 경우는 없도록 해야겠네요.
- Reference
'개발 관련 > http' 카테고리의 다른 글
1. HTTP 개관 (0) | 2022.07.14 |
---|---|
REST (2) (0) | 2022.07.14 |
REST (1) (0) | 2022.07.14 |