네트워크

HTTP 특징 및 메서드 정리

더즈 2022. 5. 7. 23:48

2장 간단한 프로토콜 HTTP

HTTP 특징

  • 클라이언트 서버 구조
  • 무상태 프로토콜(stateless), 비연결성
  • HTTP 메시지를 통해 통신
  • 단순함, 확장 가능

클라이언트 서버 구조

  • 클라이언트와 서버 간의 통신을 한다.
  • 클라이언트 - 텍스트와 이미지 등과 같은 리소스를 요구
  • 서버 - 리소스를 제공

예전에는 클라이언트와 서버라는 개념이 분리되어 있지 않았다.

하지만 분리 후

서버는 비즈니스 로직과 데이터 관리에 집중한다.

클라이언트에는 UI와 사용성에 집중한다.

양쪽이 독립적으로 진화할 수 있다!

ex) 웹, 모바일 등이 만들어져도 서버엔 변화가 적고, 트래픽이 증가해서 서버를 증설해도 클라이언트엔 변화가 적다.

무상태 프로토콜(스테이스리스), 비연결성

  • HTTP는 상태를 유지하지 않는 stateless 프로토콜이다.
  • 과거의 리퀘스트나 리스폰스 정보를 전혀 가지고 있지 않다.
    • 장점: 서버 확장성 높음
    • 단점: 클라이언트가 추가 데이터 전송

서버 확장성?

  • 중간에 다른 응답 서버로 바뀌어도 된다.
  • 트래픽이 증가할 때 서버도 대거 증설할 수 있다.
  • → 무상태는 응답 서버를 쉽게 바꿀 수 있다.

Stateless 한계

  • 모든 것을 무상태로 설계할 수 없는 경우도 있다.
  • 로그인은 상태 유지가 필요
  • 쿠키와 서버 세션 등을 사용해 상태를 유지할 수 있음
  • 상태 유지는 최소한만 사용

지속 연결

HTTP는 기본이 연결을 유지하지 않는다.

  • HTTP 초기에는 통신을 한 번 할 때마다 TCP에 의해 연결과 종료를 할 필요가 있었다.

  • 여러 데이터를 주고 받는 경우 리퀘스트 한 번 보낼 때마다 매번 TCP 연결을 종료하면 통신량이 늘어나게 된다.

  • 지금은 HTTP 지속 연결(Persistent Connections) 로 해결

  • HTTP/1.1와 일부 1.0에서 지속 연결을 사용하기 시작

  • HTTP/2, HTTP/3에서 더 많은 최적화

지속 연결

  • 1회의 TCP 커넥션 연결로 리퀘스트와 리스폰스 교환을 여러 번 한다.
  • 지속 연결은 파이프라인화를 가능하게 한다.
  • 파이프라인 - 리퀘스트 송신 후에 리스폰스를 기다리지 않고 바로 다음 리퀘스트를 보냄
  • 일반적으로 특정 시간까지 연결을 유지한다. (보통 60초)
  • 클라이언트가 연결을 끊지 않아도 서버에서 연결을 제거한다.

리퀘스트 URI

  • HTTP는 URI를 사용하여 인터넷 상의 리소스를 지정한다.

  • URI를 지정하는 방법에 여러 종류가 있다.

  • 모든 URI를 리퀘스트 URI에 지정

  • HOST 헤더 필드에 네트워크 로케이션 포함

    • GET /index.htm HTTP/1.1

      Host: hackr.jp

HTTP 메소드

GET

  • URI로 식별된 리소스를 가져올 수 있도록 요구한다.
  • 서버에 데이터를 query(쿼리 파라미터, 쿼리 스트링)를 통해서 전달
  • 메시지 바디를 사용할 수도 있지만 지원하지 않는 곳이 많아 권장하지 않음

POST

  • 요청 데이터 처리
  • 엔티티를 전송하기 위해 사용된다.
  • 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용
    • 보통 신규로 리소스를 생성되면 201 created로 응답을 보내고 Location 헤더에 리소스가 생성된 경로를 보내준다.
    • 등록된 리소스도 바디에 담아 보낸다.

리소스 생성 외 POST로 할 수 있는 것

  • 프로세스 처리
    • 주문 -> 결제 완료 -> 배달 시작 -> 배달 완료처럼 단순히 값 변경을 넘어 프로세스 상태가 변경되는 경우
    • POST의 결과로 새 리소스가 생성되지 않을 수도 있음
    • ex) POST /orders/{orderId}/start-delivery
      • URI를 리소스만으로 설계해야하지만 어쩔 수 없는 경우도 있다.
      • 위 예처럼 /start-delivery 같은 동사(행위)를 컨트롤 URI라고 함
  • 다른 메서드로 처리하기 애매한 경우
    • JSON으로 조회 데이터를 넘겨야 하는데, GET 메서드를 사용하기 어려운 경우
    • 애매하면 POST

PUT

  • 파일을 전송하기 위해서 사용된다.

  • 리퀘스트 중에 포함된 엔티티를 리퀘스트 URI로 지정한 곳에 보존하도록 요구한다.

  • 단지 HTTP/1.1 PUT 자체에 보안 기능이 없어 일반적인 웹 사이트에선 사용되지 않는다.

  • 인증 기능과 짝을 이루거나 REST와 같이 웹끼리 연계하는 설계 양식을 사용할 때 이용한다.

  • 리소스를 대체할 때 사용한다.

    • 리소스가 있으면 대체
    • 리소스가 없으면 생성
    • 쉽게 얘기해서 덮어버림
  • 중요! 클라이언트가 리소스를 식별

  • POST 요청과 달리 클라이언트가 리소스 위치를 알고 URI 지정

    • PUT /members/100 {"username":"does", "age":25}
    • POST /members {"username":"does", "age":25}
  • 100번 리소스에 대해 PUT 요청을 보내면 리소스의 데이터가 완전히 대체된다.

    • 먄약 위 데이터에서 "age"를 제외하고 PUT 요청을 보낸다면 원래 데이터에 "age"가 있었어도 사라지고 "username" 데이터만 남음

PATCH

  • 리소스 부분 변경
  • PUT이랑 달리 일부만 변경하기 때문에 위 예에서 "age"를 빼고 보닌다고 해도 "username"의 변경 부분만 적용되고 "age"의 원래 데이터는 남아 있음
  • PATCH가 지원 안되는 서버도 있다. 그럴 땐 POST를 사용하자

DELETE

  • 파일을 삭제하기 위해 사용된다.
  • PUT과 마찬가지로 인증 기능이 없어 인증 기능이나 REST를 사용하는 경우에 사용되는 경우가 있다.

HTTP 메서드 속성

  • 안전하다
  • 멱등하다
  • 캐시 가능하다

안전 (safe)

  • 호출해도 리소스를 변경하지 않는다.
  • GET은 안전

멱등 (Idempotent)

  • f(f(x)) = f(x)
  • 한 번 호출하든 n번 호출하든 결과가 똑같다.
  • 멱등 메서드
    • GET: 한 번 조회하든, 두 번 조회하든 결과가 같다.
    • PUT: 결과를 대체한다. 몇 번 대체하든 최종 결과물은 같다.
    • DELETE: 결과를 삭제한다. 여러 번 삭제해도 결과는 같다.
    • POST: 멱등이 아니다! 데이터가 중복 저장될 수 있다.
  • 활용
    • 자동 복구 메커니즘
    • 서버가 TIMEOUT 등으로 정상 응답을 못 주었을 때 클라이언트가 중복 요청 보내도 되는가에 대한 판단 근거

Q. 재요청 중간에 다른 곳에서 리소스를 변경해버리면?

  • GET → username:A, age:20
  • PUT → username:B, age:30
  • GET → username:A, age:20

A. 멱등은 외부 요인으로 중간에 리소스가 변경되는 것까지는 고려하지 않음

캐시 가능

  • 응답 결과 리소스를 캐시해서 사용해도 되는가?
  • GET, HEAD, POST, PATCH 스펙상 캐시 가능
  • 실제로는 GET, HEAD 정도만 캐시로 사용
    • 캐시를 사용하려면 캐시키를 이용해야 한다.
    • GET은 URL만 키로 잡고 구현하면 된다.
    • POST, PATCH는 본문 내용까지 캐시 키로 고려해야 하는데 구현이 쉽지 않음

쿠키

  • 스테이트리스 프로토콜의 특징은 남겨둔 채 상태를 유지하기 위해 쿠키 시스템 도입
  • 쿠키는 서버에서 리스폰스에 Set-Cookie 헤더 필드에 의해 클라이언트에 보존됨
  • 다음에 클라이언트가 같은 서버로 리퀘스트를 보낼 때 쿠키를 넣어서 송신
  • 서버는 쿠키와 서버 상의 기록을 확인해서 이전 상태를 알 수 있다.

참고