모든 개발자를 위한 HTTP 웹 기본 지식

장원령·2021년 7월 21일

Backend(Java Spring)

목록 보기
2/6

김영한님의 '모든 개발자를 위한 HTTP 웹 기본 지식'을 정리하였습니다.

1. 인터넷 네트워크

1.1 IP 프로토콜

한계

비연결성 : 패킷을 받을 대상이 없거나, 서비스 불능이어도 패킷 전송
비신뢰성 : 중간에 패킷 누수, 순서대로 안올 경우
프로그램 구분 : 같은 IP를 사용하는 서버에서 통신하는 애플리케이션이 둘 이상이면

1.2 TCP, UDP

TCP

: 연결지향 - TCP 3way handshake
: 데이터 전달 보증, 순서 보장, 신뢰할 수 있는 프로토콜

UDP

: 사용자 데이터그램 프로토콜
: 데이터 전달 보증 X, 순서 보장 X 다만 단순하고 빠르다.

1.3 PORT

: 같은 IP 내에서 프로세스 구분

1.4 DNS

: 도메인 명을 IP 주소로 바꾼다.

2. URI와 웹 브라우저 요청 흐름

2.1 URI(Uniform Resource Identifier)

URI는 locater, name 또는 둘다 추가로 분류할 수 있다
즉, URI = URL + URN

Uniform : 리소스 식별하는 통일된 방식
Resource : 자원, URI로 식별할 수 있는 모든 것
Identifier : 다른 항목과 구분하는데 필요한 정보

  • URL
    : 리소스가 있는 위치를 지정
  • URL 문법
    프로토콜(https)
    : 어떤방식으로 자원에 접근할 것인가 하는 약속 규칙 ex) https
    호스트명(www.google.com)
    : 도메인명 또는 IP주소
    포트번호(443)
    : 접속포트 일반적으로 생략 HTTPS의 경우 443
    패스(/search)
    : 리소스 경로, 계층적 구조
    쿼리 파라미터(q = hello)
    : key = value형태
    : ?로 시작 &로 추가 가능
    : 웹 서버에 제공하는 파라미터
  • URN : 리소스에 이름을 부여

: 위치는 변할 수 있지만 이름은 변하지 않는다.

2.2 웹 브라우저 요청 흐름

HTTP 메시지 전송

  1. 웹 브라우저가 HTTP 메세지 생성
  2. SOCKET 라이브러리를 통해 전달
  3. TCP/IP 패킷 생성, HTTP 메시지 포함

HTTP 메시지를 채킷으로 만들어서 요청 패킷을 전달함

3. HTTP 기본

: HyperText Transfer Protocol
: 모든 것을 HTTP 메시지에 담아서 최근에는 전송한다.
: 1997년에 나온 HTTP/1.1을 가장 많이 사용한다.
: TCP는 HTTP/1.1, HTTP/2를 UDP는 HTTP/3기반으로 한다.

특징
1. 클라이언트 서버 구조
2. 무상태 프로토콜, 비연결성
3. HTTP 메시지
4. 단순함 확장 가능

3.1 클라이언트 서버 구조

: Request Response구조
: 클라이언트는 서버에 요청을 보내고, 응답을 대기한다.
: 서버가 요청에 대한 결과를 만들어서 응답한다.
: 양쪽이 독립적으로 진행할 수 있다.
: 클라이언트가 Request를 보내면 서버가 응답할때까지 기다렸다가, 응답을 받고 동작한다.

3.2 Stateful, Stateless

  • Stateless
    : 상태를 유지하지 않음
    : 갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있다.(스케일 아웃, 수평 확장에 유리)
    : 응답 서버를 쉽게 바꿀수 있다(무한한 서버 증설 가능)
    : 서버에 장애가 있더라도 다른 서버로 교체가 용이하다.
    : 데이터를 더 많이 씀

  • Stateful
    : 상태를 유지함
    : 항상 같은 서버가 유지되어야 한다.

: 모든 것을 무상태로는 설계할 수 없기 때문에(로그인), 최소한의 상태유지만 사용해야한다.

3.3 Connectionless

장점

: 연결을 유지하고 있으면 자원 소모가 많다.
: HTTP는 기본적으로 연결을 유지하지 않는 모델이다.
: 동시에 처리하는 요청은 매우 작기 때문에, 서버 자원을 효율적으로 사용할 수 있다.

단점

: TCP/IP 연결을 새로 맺어야해서, 3way handshake 시간이 추가된다.
: 웹 브라우저로 사이트를 요청하면 수많은 자원이 함께 다운로드 된다.
: 초기에는 그랬지만, 지금은 HTTP 지속 연결을 사용한다.

: 대용량 트래픽이 올때는 최대한 Stateless하게 구성한다.

3.4 HTTP 메시지

A. 시작 라인

: request-line/status-line으로 구성된다

요청 메시지

request-line = method SP(공백) request-target Sp HTTP-version CRLF(엔터)

  • method SP = Get Post 등 서버가 수행해야 할 동작을 지정한다.
  • 요청 대상 : 절대경로 + 값을 사용한다.

응답 메시지

status-line = HTTP-version SP(공백) Status-code SP reason-phrase CRLF(엔터)

  • Status-code : 요청의 성공 실패를 나타낸다
    : 200은 성공, 400은 클라이언트 요청 오류 500은 서버 내부 오류이다
  • reason-phrase : 사람이 이해할 수 있는 짧은 상태

B. 헤더

field-name":" OWS field-value OWS(띄어쓰기 허용)
: field-name은 대소문자 구분이 없다.
: HTTP 전송에 필요한 모든 부가 정보
: 표준 헤더가 너무 많음
: 필요시 임의의 헤더 추가 기능이 있다.

C. 공백

D. 메시지 바디

: 실제 전송할 데이터, 바이트로 표현할 수 있는 모든 데이터를 전송이 가능하다.

4. HTTP 메소드

  1. API URI를 설계할떄, 가장 중요한 것은 "리소스 식별" 이다
  • 리소스란?
    : 회원의 등록, 회원의 수정이 아닌, 회원이라는 개념 자체가 리소스다.
    : 식별하기 위해서는 등록, 조회 같은 것을 배제하고, 회원이라는 리소스만 식별하고 URI에 매핑하면 된다.
  1. 다음으로 리소스와 행위를 분리해야한다.
    : 행위는 등록과 같은 동사이다. 행위를 구분하는 방법은 메소드가 한다.

4.1 HTTP 메소드

4.1.1 GET

: 리소스를 조회
: 서버에 전달하고 싶은 데이터는 쿼리를 통해서 전달한다.
: 메시지 바디를 사용해서 전달도 가능은 하지만, 지원하지 않는 곳이 많다.

4.1.2 POST

: 요청 데이터를 처리, 주로 등록에 사용
: 메시지 바디를 통해 서버로 요청 데이터를 전달한다.
: 서버는 요청 데이터를 처리한다.
: 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용한다.

대상 리소스가 리소스의 고유한 의미 체계에 따라 요청에 포함된 표현을 처리하도록 요청한다.
1. 새 리소스 생성 (등록)
2. 요청 데이터 처리
: 단순히 데이터를 생성하거나, 변경하는 것을 넘어 프로세스를 처리할 경우
: 프로세스의 상태가 변경되는 경우
3. 다른 메서드로 처리하기 애매한 경우

4.1.3 PUT

: 리소스를 대체, 해당 리소스가 없으면 생성
: 리소스를 덮어쓰기 하는 것이다.
: 클라이언트가 리소스 위치를 알고 URI 지정하는 것이 차이점

4.1.4 PATCH

: 리소스를 부분 변경

4.1.5 DELETE

: 리소스 삭제

4.2 HTTP 메소드 속성

4.2.1 안전

: 호출해도 리소스를 변경하지 않는다. (GET과 HEAD)
: 계속 호출해서 장애를 발생하는 것은 고려하지 않는다.

4.2.2 멱등 (Idempotent)

: 한번 호출하든 두번 호출하든 100번 호출하든 그 결과는 같다.
: GET, PUT, DELETE = O POST = X
: 외부 요인으로 변경된 리소스는 고려하지 않는다.

4.2.3 캐시 가능

: 응답 결과 리소르를 캐시해서 사용해도 되는가?
: GET HEAD정도만 캐시로 사용한다.

5. HTTP 메소드 활용

5.1 클라이언트에서 서버로 데이터 전송

* 데이터 전달 방식 2가지

  1. 쿼리 파라미터를 통한 데이터 전송
    : GET
    : 주로 정렬 필터(검색어)

  2. 메시지 바디를 통한 데이터 전송
    : POST, PUT, PATCH
    : 회원 가입, 상품 주문, 리소스 등록, 리소스 변경

* 4가지 상황

A. 정적 데이터 조회

: 이미지, 정적 텍스트 문서
: 조회는 GET 사용
: 정적 데이터는 일반적으로 쿼리 파라미터 없이 리소스 경로로 단순하게 조회 가능

B. 동적 데이터 조회

: 주로 정검색, 게시판 목록에서 정렬 필터
: 조회에는 GET을 사용하고 GET은 쿼리파라미터를 사용해서 데이터를 전달한다.

C. HTML Form을 통한 데이터 전송

: 회원가입, 주문, 데이터 변경 등

D. HTTP API 전송

: 서버 to 서버, 앱클라이언트, 웹 클라이언트 통신시 사용
: 회원가입, 상품 주문 데이터 변경

5.2 HTTP API 설계 예시

1. 컬렉션

: POST 기반 등록
: 대부분 사용

2. 스토어

: PUT 기반 등록

3. HTML FORM 사용

: 웹 페이지 회원 관리
: GET POST만 지원

6. HTTP 상태코드

: 클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능

6.1 1XX (Informational)

: 요청이 수신되어 처리중
: 거의 사용되지 않는다.

6.2 2XX (Successful)

: 요청 정상 처리

200 OK

201 Created

: 요청에 성공해서 새로운 리소스가 생성됨

202 Accepted

: 요청이 접수되었으나 처리가 완료되지 않았음

204 No Content

: 서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음
ex) 웹 문서 편집기의 save버튼

6.3 3XX (Redirection)

: 요청을 완료하려면 추가 행동이 필요

Redirection이란?

: 웹 브라우저는 3XX 응답의 결과에 Location 헤더가 있으면 Location위치로 자동 이동한다.
: 리다이렉션의 종류는 아래와 같다.

  1. 영구 리다이렉션
    : 특정 리소스의 URI가 영구적으로 이동한다.
    : /event -> /new-event

  2. 일시 리다이렉션
    : 일시적인 변경
    : 주문 완료 -> 주문 내역 화면으로 이동
    : PRG

  3. 특수 리다이렉션
    : 결과 대신 캐시를 사용

300 Multiple Choices

1. 영구적인 리다이렉션

: 리소스의 URI가 영구적으로 이동
: 원래의 URL을 사용 하지않고, 검색 엔진 등에서도 변경 인지

301 Moved Permanently

: 리다이렉트시 요청 메소드가 GET으로 변하고 본문이 제거될 수 있다.
: 실무에선 주로 301을 사용

308 Permanent Redirect

: 리다이렉트시 요청 메서드와 본문 유지

2. 일시적인 리다이렉션

: 검색 엔진 등에서 URL을 변경하면 안됨

302 Found

: 리다이렉트시 요청 메소드가 GET으로 변하고 본문이 제거될 수 있다.

303 See Other

: 302와 기능은 같다
: 리다이렉트시 요청 메소드가 GET으로 변경

307 Temporary Redirect

: 302와 기능은 같다.
: 리다이렉트시 요청 메소드와 본문 유지한다.
: 요청 메서드는 변경하면 안된다 반드시

3. 기타

304 Not Modified

: 캐시를 목적으로 사용
: 클라이언트에게 리소스가 수정되지 않았음을 알려주고, 클라이언트는 로컬 PC에 저장된 캐시를 재사용한다.
: 304 응답은 응답에 메시지 바디를 포함하면 안된다.
: 조건부 Get HEAD 요청시에 사용된다.

PRG

: POST로 주문 후에 웹 브라우저를 새로고침하면 새로고침은 다시 요청된다.
: 중복 주문이 될 수 있다.

6.4 4XX (Client Error)

: 클라이언트 오류, 잘못된 문법 등으로 서버가 요청을 수행할 수 없음
: 오류가 클라이언트에 있을때

400 Bad Request

: 요청 구문 메시지 등등의 오류이다.

401 Unathorized

: 클라이언트가 해당 리소스에 대한 인증이 필요함

403 Forbidden

: 서버가 요청을 이해했지만 승인을 거부함

404 Not Found

: 요청 리소스가 서버에 없음

6.5 5XX (Server Error)

: 서버가 정상 요청을 처리하지 못함
: 오류가 서버에 있을 때

500 Internal Server Error

: 서버 문제로 오류 발생

503 서비스 이용 불가

: 서버가 일시적인 과부하 또는 예정된 작업으로 요청을 처리할 수없음

7. HTTP 헤더 - 일반 헤더

: HTTP 전송에 필요한 모든 부가정보를 담는다.
: 필요시 임의의 헤더도 추가가 가능하다.

HTTP 헤더의 분류

  1. General 헤더 : 메시지 전체에 적용되는 정보
  2. Request 헤더: 요청 정보
  3. Response 헤더 : 응답 정보
  4. Entity 헤더 : 엔티티 바디 정보

HTTP 바디

: 메시지 본문은 엔티티 본문(요청이나 응답에서 전달할 실제 데이터)를 전달하는데 사용 된다.
: 엔티티 헤더는 엔티티 본문 해석에 대한 정보를 제공함.

7.1 표현 헤더

: Content-Type, Content-Encoding, Content-Language, Content-Length

7.2 콘텐츠 협상 헤더

: 클라이언트가 선호하는 표현을 요청한다. 요청시에만 사용
: Accept, Accept-Charset, Accept-Encoding, Accept-Language
: 이 때, 원하는것이 없을 경우에 대비해 우선순위가 들어온다.

7.3 전송 방식

  1. 단순전송
  2. 압축전송
  3. 분할전송
  4. 범위전송

7.4 일반 정보

: From. Referer, User-Agent, Server, Date

  1. From
    : 유저 에이전트의 이메일 정보

  2. Referer
    : 이전 웹 페이지의 주소

  3. User-Agent
    : 클라이언트의 애플리케이션 정보, 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
    : 요청에서 주로 사용된다.

  4. Server
    : 요청을 처리하는 Origin서버의 소프트웨어 정보

  5. Date
    : 메시지가 발생한 날짜와 시간

7.5 특별한 정보

  1. Host
    : 요청한 호스트 정보(도메인)

  2. Location
    : 페이지 리다이렉션

  3. Allow
    : 허용 가능한 HTTP 메서드

  4. Retry-After
    : 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
    : 503 서비스가 언제까지 불능인지 알려줄 수 있음

7.6 인증

  1. Authorization
    : 클라이언트 인증 정보를 서버에 전달
  2. WWW-Authenticate
    : 리소스 접근시 필요한 인증 방법 정의

7.7 쿠키

: HTTP는 무상태 프로토콜이다.
: 클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어진다.
: 클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못하고, 서로 상태를 유지하지 않는다.

  • 쿠키를 사용하지 않을 경우 문제점
    : 상태를 유지하기 위하여 모든 요청과 링크에 사용자 정보를 포함해서 보낸다면 문제가 생김

쿠키 사용 단계

  1. 웹 브라우저에서 POST 보냄
  2. 서버가 SET-Cookie라고 정보를 담아 보냄
  3. 웹 브라우저 내의 쿠키 저장소에 정보를 담아 저장함.
  4. 로그인 이후 main page접근 시 서버에 요청을 보낼때마다 쿠키 값을 찾아서 Cookie 정보를 찾아서 보낸다.

쿠키의 특징

: 모든 요청에 쿠키 정보가 자동으로 포함된다.
: 이는 트래픽을 유발하기 때문에 세션 ID, 인증 토큰 정도의 최소한의 정보만 사용한다.
: 보안에 민감한 데이터는 저장하면 안된다.

생명 주기

영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지
세션 쿠키 : 만료 일자를 생략하면 브라우저 종료까지만 유지된다.

도메인

명시할 경우 : 명시한 문서 도메인 + 서브 도메인
생략할 경우 : 하위 도메인은 쿠키 접근 불가

경로

: 경로를 포함한 하위 경로 페이지만 쿠키 접근이 가능하다.

보안

: Secure, HttpOnly, SameSite

8. HTTP 헤더 - 캐시

8.1 캐시 기본 동작

: 캐시가 없을 때는, 데이터가 변경되지 않아도 매번 네트워크를 통해서 데이터를 다운로드 받아야 하고, 이때문에 매우 느리고 비싸게 된다.
: 캐시 덕분에, 캐시 가능 시간 동안은 네트워크를 사용하지 않아도 돼서 보다 빠르게 브라우저를 이용할 수 있다.

8.2 캐시 시간 초과

: 캐시 만료 후에도 서버에서 데이터를 변경하지 않았으면 캐시의 데이터를 그대로 사용이 가능한데, 클라이언트의 데이터와 서버의 데이터가 같은지 확인할 수 있는 검증이라는 방법이 필요하다.

검증 헤더

  1. Last-Modified
    : 캐시가 가지고 있는 헤더의 데이터 최종 수정일을 비교한다.
    : 1초 미만 단위로 캐시 기반이 불가능하고 날짜 기반의 로직을 사용한다.

  2. Etag
    : 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠 데이터 변경시 이 이름을 바꿔서 변경함
    : Etag가 같은지 다른지에 따라 갈린다.
    : 캐시 제어 로직을 서버에서 완전히 관리

조건부 요청 헤더

: 검증 헤더로 조건에 따른 분기
: 조건에 만족하면 200 OK, 조건 만족하지 않을 시 304 Not Modified
: Last-Modified는 If-Modified-Since와 같이 쓰인다.
: ETag는 if-none-Match와 같이 쓰인다.

8.3 캐시와 조건부 요청 헤더

  1. Cache-Control (캐시 제어)
    max -age : 캐시 유효 시간, 초 단위
    no-cache : 데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용
    no-store : 데이터에 민감한 벙보가 있으니 저장하면 안됨

  2. Pragma (캐시 제어 (하위 호환))
    : 거의 사용하지 않음

  3. Expires (캐시 유효 기간 (하위 호환))
    : 캐시 만료일을 정확한 날짜로 지정 Cache-Control 권장함

8.4 프록시 캐시

: 서버가 멀리 떨어져있을 경우, 시간이 오래 걸리기 때문에, 가까운곳에 거쳐서 오도록 중간 기점의 서버를 사용하는 것

캐시 지시어 - 기타

  1. public
    : 응답이 public 캐시에 저장되어도 됨

  2. private
    : 응답이 해당 사용자만을 위해 private캐시에 저장해야 함

  3. s-maxage
    : 프록시 캐시에만 적용되는 max-age

  4. Age:60
    : 오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간

8.5 캐시 무효화

  1. no-cache
    : 데이터는 캐시해도 되지만, 원 서버에 검증하고 사용

  2. no-store
    : 데이터에 민감한 정보가 있으니 저장 하면 안됨

  3. must-revalidate
    : 캐시 만료 후 최초 조회시 원 서버에 검증해야 함
    : 원 서버 접근 실패시 반드시 504 오류가 발생해야 함
    : 캐시 유효 기간이라면 캐시를 사용함

  • Pragma: no-cache
    : HTTP 1.0 하위 호환

0개의 댓글