[Network] 6-1. HTTP

KYJ의 Tech Velog·2023년 4월 24일
0

Network

목록 보기
9/21
post-thumbnail

HTTP

HTTP(HyperText Transfer Protocol)는 하이퍼텍스트를 빠르게 교환하기 위한 프로토콜로, 서버와 클라이언트 사이에서 어떻게 메시지를 교환할지 정해놓은 규칙입니다. 요청과 응답으로 구성되어 있으며 80번 포트를 사용합니다. 간단한 예시로 클라이언트가 웹 페이지에서 링크가 걸려 있는 텍스트를 클릭(요청)하면 링크를 타고 새로운 페이지로 넘어갑니다(응답). 우리가 사용하는 웹 브라우저에서 인터넷 주소 앞에 들어가는 http://가 이 프로토콜을 사용해서 정보를 교환하겠다는 표시입니다.


Stateless

서버가 클라이언트의 이전 상태를 보존하지 않는다는 의미입니다. 서버에 클라이언트의 이전 상태를 저장하지 않기 때문에 서버 확장에 용이합니다. 하지만 클라이언트가 매번 데이터를 추가 전송해야 합니다.

Example

Stateful
고객: 이 사과는 얼마인가요?
점원: 3000원입니다.

고객: 2개 구매할게요.
점원: 6000원입니다. 신용카드, 현금 중에 어떤 걸로 결제하시겠어요?
(구매 상품수량에 대한 state 저장/유지)

고객: 신용카드로 하겠습니다.
점워: 6000원 결제되었습니다.
(구매 상품, 수량, 결제 수단에 대한 state 저장/유지)

다음과 같은 상황에는 점원(서버)이 바뀐다면 저장한 정보들을 바뀌는 점원(서버)에 미리 알려주어야 합니다. 알려주지 않는다면 다음과 같은 상황이 벌어집니다.

Stateful
고객: 이 사과는 얼마인가요?
점원: 3000원입니다.

고객: 아까 말씀드린 대로 구매할게요.
점원: 어떻게 구매하신다는 거죠?

이처럼 점원(서버)이 바뀌면 통신에 문제가 생깁니다. 따라서 점원(서버)이 바뀌지 않아야 하는데 점원(서버)에게 문제(서버 장애 등...)가 생긴다면 문제가 커집니다. 따라서 서버의 확장이 쉽지 않습니다.

매번 서버가 정보를 저장하지 않고 클라이언트가 서버에게 정보를 알려주면 다른 서버와 통신하더라도 문제가 없습니다. 클라이언트의 요청에 어느 서버가 응답하더라도 상관없다는 의미입니다. 클라이언트의 요청이 대폭 증가해도 서버를 증설해서 해결할 수 있습니다.


Connectionless

클라이언트가 서버에 요청을 하고 응답을 받으면 연결을 끊어 연결을 유지하지 않는 것입니다. 연결을 유지하기 위해서는 서버의 자원을 계속 소모하게 됩니다.

Connectionless하면 다수의 클라이언트가 서버와 통신을 하여도 실제 서버에서의 동시 처리 요청은 매우 적게 됩니다. 따라서 서버 자원을 효율적을 사용할 수 있습니다.

하지만 매번 TCP/IP 연결을 계속 새로 맺어야 해서 3-Way HandShake 시간이 소요됩니다. 또한 웹 사이트 요청 시 많은 자원을 다운로드해야하고 자원마다 연결을 생성하기 때문에 오버헤드가 큰 단점이 있습니다.

Persistent Connection

이를 어느 정도 해결하기 위해 한 오브젝트를 보내고 연결을 끊는 것이 아니라, 일정 시간동안 동일한 TCP 연결을 사용해서 여러 개의 HTTP 요청을 처리하는 방식을 사용합니다.

Persistent Connection을 맺는 기법 중 하나로 HTTP keep-alive라는 것이 있습니다.

HTTP keep-alive vs TCP keep-alive

엄연히 다른 개념입니다. HTTP keep-alive 애플리케이션에서 수행되는 것이고, TCP keep-alive는 OS에서 수행되는 것입니다. 또한 TCP keep-alive의 주요한 목적은 죽은 Peer를 확인하는 것입니다. HTTP keep-alive는 매번 TCP 연결을 맺어야 하는 비용을 줄이는 것이 주요한 목적입니다.


HTTP Message

Request

Start Line은 세 가지 부분으로 구성됩니다. HTTP Method, Request Target, HTTP Version 입니다. HTTP Method는 요청의 의도를 담고 있습니다. 여기에선 GET 입니다. Request Target은 HTTP Request가 전송되는 목표 주소입니다. HTTP Version은 version에 따라 메시지 구조나 데이터가 다를 수 있기 때문에 명시되어야 하는 정보입니다.

Headers에는 요청에 대한 추가 정보가 담겨 있습니다. Body에는 요청에서 전송하고자 하는 데이터를 담고 있는 부분입니다. 데이터가 없다면 body는 비어 있습니다.

Response

Status Line은 응답의 상태를 간략하게 나타내줍니다. HTTP Version, Status Code, Status Text 세 가지 부분으로 구성됩니다. Status Code에 대해서는 따로 포스팅 하도록 하겠습니다.

Headers와 Body는 Request와 동일합니다.


HTTP Method

HTTP Method는 서버가 수행해야 할 동작을 지정하는 요청을 보내는 방법입니다.

HTTP Method의 멱등성

멱등성이란 같은 연산을 여러번 실행한다고 해도 그 결과가 달라지지 않는 성질을 의미합니다. 어떠한 값에 동일한 연산을 여러 번 한다 하더라도 동일한 결과값을 내어준다는 것입니다.

HTTP 에서도 동일하게 적용될 수 있습니다. 동일한 요청을 한 번 보내는 것과 여러 번 보내는 것이 동일한 효과를 지니고, 서버의 상태도 동일하게 남을 때 해당 HTTP Method가 멱등성을 갖는다고 이야기합니다.

Safe Methods

서버의 상태를 변경시키지 않는 메소드를 의미합니다. 모든 안전한 메소드는 멱등성을 갖지만, 역은 성립하지 않습니다.

멱등성은 메소스가 서버의 상태를 변경시키지 않는 것이 아닙니다. 멱등성은 요청에 대한 서버의 상태가 항상 같은가가 핵심입니다.

GET

리소스의 조회에 사용되는 메소드입니다. 서버에 전달하고 싶은 데이터를 Query(Parameter, Query String)를 통해 전달합니다. 메시지 바디를 통해 데이터를 전달할 수 있지만 지원하지 않는 곳도 존재하기 때문에 권장하지 않습니다.

단순히 읽어오기만 하는 메소드이기 때문에 멱등하다고 할 수 있습니다. 서버의 상태가 변하지 않기 때문에 안전하다고도 할 수 있습니다.

POST

메시지 바디를 통해 서버로 요청 데이터를 전달합니다. 서버는 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행합니다. 주로 신규 리소스의 등록, 프로세스 처리 등에 사용합니다.

다른 메소드로 처리하기 애매한 경우 주로 사용됩니다. 조회할 때 데이터를 넘기기 어려운 경우 데이터를 넘기는 데 사용할 수도 있습니다.

메소드가 호출될 때마다 데이터베이스 등에 요청된 데이터가 추가될 것입니다. 이는 멱등성을 위배함을 의미합니다. 호출 시마다 서버의 상태가 달라지기 때문입니다. 다만 서버의 상태가 달라지기 때문에 안전하지는 않습니다.

PUT

목적 리소스를 현재 메시지의 값으로 생성하거나 만약 존재한다면 기존 리소스를 삭제하고 덮어쓰기합니다.

PUT은 POST와 다르게 클라이언트가 리소스의 구체적인 전체 경로를 지정해 보내줘야 합니다. 기존 데이터를 대체해줘야 하기 때문입니다.

리소스를 요청에 담긴 내용대로 통째로 대체하기 때문에 여러 번 수행되어도 결과 값이 바뀌지 않습니다. 따라서 PUT도 멱등하다고 할 수 있습니다. 리소스를 수정하는 것이기 때문에 서버의 상태가 변해서 안전하다고 할 수 없습니다.

PATCH

리소스를 부분적으로 변경합니다. 지원하지 않는 경우도 있어서 POST로 대체하여 사용하기도 합니다.

PUT 처럼 리소스를 전부 대체한다면 멱등하겠지만 부분적으로 리소스를 변경하는 경우에는 멱등성을 위배할 것입니다. PUT과 마찬가지로 안전하다고 할 수 없습니다.

DELETE

특정 리소스의 삭제를 요청하는 데에 사용합니다.

존재하지 않는 결과를 삭제하려고 하는 것이 서버의 상태 자체를 바꾸는 것은 아니기 때문에 멱등할 것입니다. 하지만 처음 실행 시 서버의 상태가 변하는 것이기 때문에 안전하진 않습니다.

기타 메소드

잘 사용되지 않는 메소드입니다.

  • HEAD
    GET과 동일하지만 메시지 마디를 제외하고 반환
  • OPTIONS
    대상 리소스에 대한 통신을 설정하는 데 사용
  • CONNECT
    대상 자원으로 식별되는 서버에 대한 터널을 설정
  • TRACE
    대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행

0개의 댓글