이 글은 인프런 김영한 님의 강의 '모든 개발자를 위한 HTTP 웹 기본 지식'을 바탕으로 정리한 내용입니다.
HTTP (HyperText Transfer Protocol)
HTTP는 HTML과 같은 하이퍼미디어 문서를 전송하기위한 애플리케이션 계층 프로토콜이다. HTML뿐만 아니라 요즘에는 거의 모든 형태의 데이터 전송이 가능하다. 그래서 지금은 HTTP의 시대이다.
HTTP의 역사로 놓고 보면 여러 버전이 있지만 HTTP/1.1 버전을 많이 사용하고 주요한 기능들이 다 들어있다. HTTP/2나 HTTP/3 버전도 HTTP/1.1에서 성능을 개선한 버전이다.
HTTP는 클라이언트-서버 구조, 무상태성, 비연결성, HTTP 메시지, 단순함, 확장 가능이라는 특징을 가지고 있다.
클라이언트-서버 구조는 클라이언트는 서버에 요청을 보내고, 응답이 올 때까지 대기한다. 서버는 요청에 대한 결과를 만들어서 응답해준다.
무상태 프로토콜(Stateless)은 서버가 클라이언트의 상태를 보존하지 않는다는 것이다. 사실 무상태라는 말은 많이 들었고 접해봤지만 이해하기 쉽지 않았지만 무상태를 유지하면서 얻을 수 있는 장점을 예시로 보니 쉽게 이해가 가능했다.
클라이언트가 여러 개의 서버들 중 하나의 서버와 상태성을 가진 채 연결을 하던 중에 서버에 장애가 나면 이전까지 했던 요청들은 다 사라지고 다른 서버와 처음부터 다시 요청을 시도해야 한다.
하지만 무상태성을 가지면 중간에 서버가 에러가 나도 이전 서버에서 상태를 보관하지 않기 때문에 다른 서버와 연결을 한다고 해도 문제 될 것이 없다. (그림으로 보면 이해가 빠를 것 같아 아래 그림을 참고하면 좋을 것 같다.)

하지만 모든 것을 무상태로 설계할 수는 없다. 상태를 유지해야 하는 것도 있기 때문에 최대한 무상태성으로 설계하고 상태 유지는 최소한으로 사용하자.
비연결성은 HTTP는 기본이 연결을 유지하지 않는 모델이다. 그렇기 때문에 매우 효율적으로 서버 자원을 사용할 수 있다. 단, TCP/IP는 3 ways handshake 연결을 새로 맺어야 하므로 시간이 걸린다는 한계를 가졌지만 최근에 최적화를 통해서 한계를 극복했다.
HTTP 메서드
GET
- 리소스 조회
- 서버에 전달하고 싶은 데이터는 query(쿼리 파라미터, 쿼리 스트링)를 통해서 전달
Post
- 요청 데이터 처리, 주로 등록에 사용
- 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다.
Put
- 리소스를 대체(리소스가 있다면 대체하고 없다면 생성한다.)
- 클라이언트가 리소스를 식별한다는 것이 중요! -> 클라이언트가 리소스 위치를 알고 URI를 지정한다는 것이 Post와 차이
- 리소스를 완전히 대체한다.( username과 age에 대한 정보를 가진 리소스에 age만 Put 한다면 기존의 username은 사라짐)
Patch
- 리소스 부분 변경
- Put과 달리 부분만 변경한다.(즉, username과 age에 대한 정보를 가진 리소스에 age만 Patch 한다면 Put과 달리 기존의 username을 가진 채 age에 대한 정보만 바뀐다.)
Delete
- 리소스 제거
HTTP 메서드 활용
클라이언트에서 서버로 데이터를 전송 방식은 두 가지로 나뉜다.
- 쿼리 파라미터를 통한 데이터 전송
- 메시지 바디를 통한 데이터 전송
쿼리 파라미터를 통한 데이터 전송은 GET방식이고 주로 정렬 필터에 사용한다.
메시지 바디를 통한 데이터 전송은 POST, PUT, PATCH방식이고 회원 가입, 상품 주문, 리소스 등록, 리소스 변경 등에 사용한다.
4가지 상황으로 나눠 보면 정적 데이터 조회, 동적 데이터 조회, HTML FORM을 통한 데이터 전송 , HTTP API를 통한 데이터 전송이 있다.
- 정적 데이터 조회 : 일반적으로 쿼리 파라미터 없이 리소스 경로로 단순하게 조회 가능
- 동적 데이터 조회 : 조회 조건을 줄여주는 필터, 조회 결과를 정렬하는 정렬 조건에 주로 사용, 쿼리 파라미터 사용해서 데이터를 전달
- HTML Form 데이터 전송 : HTML Form 전송은 GET, POST만 지원
- HTTP API 데이터 전송 : POST, PUT, PATCH: 메시지 바디를 통해 데이터 전송
HTTP API 설계 예시
HTTP API - 컬렉션
- POST 기반 등록
- 클라이언트는 등록될 리소스의 URI를 모른다.
- 서버가 URI를 생성하고 관리한다.
HTTP API - 스토어 (클라이언트가 리소스를 관리하는 저장소)
- PUT 기반 등록
- 클라이언트가 리소스의 URI를 알고 있어야 한다.
HTML FORM 사용
- GET, POST만 지원 ( 그래서 제약이 있다.)
URI를 설계할 때, 최선의 방법은 리소스만 가지고 설계를 하는 것이다. 하지만 항상 한계를 존재하는 법이고 실무에서 리소스만 가지고 URI를 설계하는 것은 불가능하다. 그래서 컨트롤 URI를 사용한다. 강조하고 싶은 건 최대한 리소스를 가지고 URI를 설계하고 정 안될 때 컨트롤 URI를 사용하도록 하자.
여기서 말하는 리소스란?
-> 회원 목록을 조회한다고 했을 때, 회원이 리소스(명사를 지칭한다고 보면 쉬울 것이다)이다. 그래서 이 회원이라는 리소스를 가지고 최대한 URI를 설계한다는 것이다. 반면에 컨트롤 URI는 동사라고 보면 쉽다. 회원 목록 조회라고 했으니 회원이라는 리소스와 조회라는 동사가 같이 URI로 설계되는 것을 말한다.
HTML FORM은 GET과 POST방식만 지원하기 때문에 제약이 있다고 했다. 그래서 이런 제약을 해결하기 위해 컨트롤 URI를 사용하는 것이다.
HTTP 상태 코드
- 1xx (Informational): 요청이 수신되어 처리중
- 2xx (Successful): 요청 정상 처리
- 3xx (Redirection): 요청을 완료하려면 추가 행동이 필요
- 4xx (Client Error): 클라이언트 오류, 잘못된 문법등으로 서버가 요청을 수행할 수 없음
- 5xx (Server Error): 서버 오류, 서버가 정상 요청을 처리하지 못함
1xx
-> 거의 사용되지 않는다.
2xx (성공)
- 200 OK : 요청 성공
- 201 Created : 새로운 리소스가 생성
- 202 Accepted : 요청이 접수되었으나 처리되지 않음
- 204 No Content : 요청에 성공했으나 응답 본문에 보낼 데이터가 없음
3xx (리다이렉션)
- 300 Multiple Choices : 거의 사용 X
- 301 Moved Permanently : 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
- 302 Found : 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
- 303 See Other : 리다이렉트시 요청 메서드가 GET으로 변경
- 304 Not Modified : 캐시를 목적으로 사용
- 307 Temporary Redirect : 리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안된다.)
- 308 Permanent Redirect : 리다이렉트시 요청 메서드와 본문 유지(처음 POST를 보내면 리다이렉트도 POST 유지)
영구 리다이렉션 : 특정 리소스의 URI가 영구적으로 이동
일시 리다이렉션 : 일시적인 변경
특수 리다이렉션 : 결과 대신 캐시를 사용
PRG : Post/Redirect/Get
-> Post 요청 후 새로 고침으로 중복된 요청이 되는 것을 막기 위해 Post 요청후 Get 메서드로 리다이렉션하는 것.
그래서 새로 고침하면 Get 메서드로 Get 요청만 계속하게 되므로 Post 중복 요청으로 인해 생기는 문제를 막을 수 있음.
4xx (클라이언트 오류)
- 400 Bad Request : 클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없음
- 401 Unauthorized : 클라이언트가 해당 리소스에 대한 인증이 필요함
- 403 Forbidden : 서버가 요청을 이해했지만 승인을 거부함
- 404 Not Found : 요청 리소스를 찾을 수 없음
5xx (서버 오류)
- 500 Internal Server Error : 서버 문제로 오류 발생
- 503 Service Unavailable : 서비스 이용 불가
'Web' 카테고리의 다른 글
토큰이란 ? (토큰 기반 인증 VS 서버 기반 인증) (0) | 2022.06.15 |
---|---|
REST란? REST API 와 RESTful API (0) | 2022.06.13 |
캐시(Cache) (0) | 2022.05.23 |
쿠키와 세션 (0) | 2022.05.19 |
웹 기본 지식 (0) | 2022.05.17 |