김영한 님의 [ 모든 개발자를 위한 HTTP 강의 ] 를 듣고 정리한 내용입니다.
HTTP 메서드는 언제 활용하는가
클라이언트에서 서버로 데이터 전송 시 사용한다
보통 클라이언트에서 서버로 데이터 전송시 데이터 전달 방식은 크게 2가지 방식이 존재한다.
1. 쿼리파라미터를 통한 데이터 전송
- GET
- 주로 정렬 필터(검색어)
2. 메세지 바디를 통한 데이터 전송
- POST, PUT, PATCH
- 회원가입, 상품주문, 리소스 등록, 리소스 변경
정적 데이터 조회
정적 데이터 조회 시 쿼리파라미터 미사용한다.
조회를 할 시 GET 메서드를 사용한다.
정적데이터는 일반적으로 쿼리 파라미터 없이 리소스 경로로 조회가 가능하다.
동적 데이터 조회
쿼리파라미터를 사용한다.
주로 검색 게시판 목록에서 정렬 필터(검색어) 사용
조회 조건을 줄여주는, 조회 결과를 정렬하는 정렬조건에 주로 사용한다.
조회는 GET 사용
GET은 쿼리 파라미터 사용해서 데이터를 전달한다.
HTML Form 데이터 전송
form action을 보면 /save 경로로 요청을 보내고 있다.
POST 전송으로 - 서버 내부의 값의 상태가 변해야되는 경우 사용한다.
잘못된 예시를 봐보자,
GET은 조회에만 사용해야한다. 리소스 변경이 발생하는 곳에 사용하면 안된다.
만약 POST로 클라이언트에서 서버로파일을 보내야 되는 경우.
Http메시지는 Content-Type 속성을 multipart/form-data 로 지정되며 정해진 형식에따라
메세지를 인코딩하여 전송된다.
서버는 이를 처리하기 위해 멀티파트 메세지에대해 각 파트별로 분리해서 개별 파일의 정보를 얻게된다.
HTTP 통신규격을 보면
1. Content-Type이 multipart/form-data로 지정되어있어야 서버에서 정상적으로 처리가 가능하다.
2. 전송되는 파일 데이터의 구분자로 boundary 에 지정되어 있는 문자열을 이용한다.
3. boundary 의 문자열 중 마지막 값은 다른값과 다르게 -- 이 마지막에 붙었는데 -- 는 body의 끝을 알리는 의미를 가진다.
정리하자면
HTML Form submit 시 POST 전송을 하는 경우는
- ex) 회원가입, 상품주문, 데이터 변경
Content-Type : application-x-www-form-urlencoded 사용
- form의 내용을 메시지 바디를 통해서 전송 (key=value, 쿼리 파라미터 형식)
- 전송 데이터를 url encoding 처리
HTML Form은 GET 전송도 가능하다.
다만. 서버 내부의 리소스를 변경하는 경우에는 사용하지 않는다.
Content-Type : multipart/form-data
- 파일 업로드 같은 바이너리 데이터 전송 시 사용한다.
- 다른 종류의 여러 파일과 폼의 내용 함께 전송이 가능하다
HTML Form 전송은 GET, POST 2개만 지원한다.
HTTP API 데이터 전송
- 서버에서 서버로 통신할때
- 앱 클라이언트
- 웹 클라이언트
HTML에서 Form 전송 대신 자바 스크립트를 통한 통신에 사용(AJAX)
React, VueJS 같은 웹 클라이언트와 API 통신
POST, PUT, PATCH 메시지 바디를 통해 데이터 전송
GET : 조회, 쿼리 파라미터로 데이터 전달
Content-Type : application/json 을 주로 사용한다 (사실상 표준)
HTTP API 설계 예시
HTTP API - 컬렉션
- POST 기반 등록
POST /api/posts
컬렉션은 클라이언트가 서버에 데이터를 추가하기 위해 사용하는 HTTP API 이다.
데이터를 추가하는데에는 보통 POST 메서드를 사용한다
HTTP API - 스토어
- PUT 기반 등록
- ex) 정적 컨텐츠 관리, 원격 파일 관리
PUT /api/products/123
보통 데이터를 수정(등록) 하는데 사용된다.
HTML FORM 사용
- 웹페이지 회원관리
- GET , POST만 지원
특정 회원정보 조회같은 데이터를 가져오는 작업은 GET
새로운 회원을 등록하는 작업은 POST를 사용한다.
회원관리 시스템 (POST 기반 등록)
- 회원 목록 /members -> GET
- 회원 등록 /members -> POST
- 회원 조회 /members/{id} -> GET
- 회원 수정 /members/{id} -> PATCH,PUT,POST
- 회원 삭제 /members/{id} -> DELETE
POST - 신규 자원 등록 특징
클라이언트는 등록될 리소스의 URI를 모른다.
회원등록 /members -> POST
POST /members
서버가 새로 등록된 리소스 URI를 생성해준다
HTTP 1.1 201 Created
Location: /members/100
컬렉션(Collection)이란.
서버가 관리하는 리소스 디렉토리
서버가 리소스의 URI를 생성하고 관리
여기서 컬렉션은 /member
파일관리 시스템 (PUT 기반 등록)
- 파일 목록 /files -> GET
- 파일 조회 /files/{filename} -> GET
- 파일 등록 /files/{filename} -> PUT
- 파일 삭제 /files/{filename} -> DELETE
- 파일 대량 등록 /files -> POST
PUT - 신규 자원 등록 특징
클라이언트가 리소스 URI 를 알고 있어야 한다.
파일등록 /files/{filename} -> PUT
PUT /files/star.jpg
클라이언트가 직접 리소스의 URI를 지정한다.
스토어(Store)란?
클라이언트가 관리하는 리소스 저장소
클라이언트가 리소스의 URI 를 알고 관리
여기서 스토어는 /files
HTML FORM 사용
- 회원목록 /members -> GET
- 회원 등록 폼 /members/new -> GET
- 회원 등록 /members/new , /members -> POST
- 회원 조회 /members/{id} -> GET
- 회원 수정 폼 /members/{id}/edit -> GET
- 회원 수정 /members/{id}/edit , /members/{id} -> POST
- 회원 삭제 /members/{id}/delete -> POST
HTML FORM은 GET,POST만 지원
컨트롤 URI
HTML FORM 방식은 GET,POST 만 지원하므로 제약이 있다.
이런 제약을 해결하기 위해 동사로 된 리소스 경로 사용한다.
POST의 /new, /edit, /delete 가 컨트롤 URI
HTTP 메서드로 해결하기 어려운 경우 사용한다.
HTTP 상태코드
클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능이다.
- 1xx ( Informational ) : 요청이 수신되어 처리중
- 2xx ( Successful ) : 요청 정상 처리
- 3xx ( Redirection ) : 요청을 완료하려면 추가 행동이 필요
- 4xx ( Client Error ) : 클라이언트 오류 , 잘못된 문법 등으로 서버가 요청을 수행할 수 없음
- 5xx ( Server Error ) : 서버오류, 서버가 정상 요청을 처리하지 못함
만약 모르는 상태코드가 나와도
클라이언트는 상위 상태코드로 해석해서 처리한다.
ex)
299 ??? -> 2xx ( Successful )
451 ??? -> 4xx ( Client Error )
599 ??? -> 5xx ( Server Error )
1xx (Informational)
요청이 수신되어 처리중
2xx (Successful)
성공
클라이언트의 요청을 성공적으로 처리
200 OK
201 Created
202 Accepted
요청이 접수되었으나 처리가 완료되지 않음
- 배치 처리 같은 곳에서 사용한다
- 예 ) 요청 접수 후 1시간 후 배치 프로세스가 요청을 처리한다.
204 No Content
서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음
ex) 웹 문서 편집기의 save 버튼
- save 버튼의 결과로 아무 내용이 없어도 된다.
- save 버튼을 눌러도 같은 화면을 유지해야 한다
- 결과 내용이 없어도 204 메세지(2xx) 만으로 성공 인식 가능하다.
3xx - 리다이렉션
요청을 완료하기 위해 유저 에이전트의 추가 조치 필요
- 300 Multiple Choices
- 301 Moved Permanently
- 302 Found
- 303 See Othor
- 304 Not Modified
- 307 Temporary Redirect
- 308 Permanent Redirect
리다이렉션의 이해
웹 브라우저는 3xx 응답 결과에 Location 헤더가 있으면, Location 위치로 자동으로 이동한다
리다이렉션 종류
영구 리다이렉션 - 특정 리소스의 URI 가 영구적으로 이동
- ex) /members -> /users
일시 리다이렉션 - 일시적인 변경
- ex)주문 완료 후 주문 내역 화면으로 이동
- PRG 패턴 : Post/ Redirect/ Get
특수 리다이렉션
- 결과대신 캐시를 사용
영구 리다이렉션 301, 308
리소스의 URI 가 영구적으로 이동
원래의 URL을 사용하지 않을 경우, 검색 엔진에서도 변경 인지
301 Moved Permanently
리다이렉트 요청 시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
308 Permanent Redirect
301과 기능은 같음
리다이렉트 요청 시 요청 메서드와 본문 유지 ( 처음 POST 보내면 리다이렉트도 POST로 유지)
일시적인 리다이렉션 302, 307, 303
리소스의 URI가 일시적으로 변경
검색엔진등에서 URL을 변경하면 안된다.
302 Found
리다이렉트가 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
307 Temporary Redirect
302와 기능은 같음
리다이렉트 시 요청 메서드와 본문 유지 ( 요청 메서드를 변경하면 안된다 )
303 See Other
302와 기능은 같음
리다이렉트 시 요청 메서드가 GET으로 변경
PRG : Post/Redirect/Get
Post 주문 후 웹브라우저를 새로고침 하면 다시 Post 요청이 반복된다.
중복 주문이 된다.
POST로 주문 후 새로고침으로 인한 중복 주문 방지
POST로 주문 후 주문 결과 화면을 GET 메서드로 리다이렉트
새로고침해도 결과 화면을 GET으로 조회
중복 주문 대신에 결과 화면만 GET으로 다시 요청
PRG 패턴 적용 후 리다이렉트 시
- URL 이 이미 POST -> GET 으로 리다이렉트 됨
- 새로고침해도 GET으로만 결과화면만 조회
정리
302 Found - > GET 으로 변할 수 있음
307 Temporary Redirect -> 메서드가 변하면 안됨
303 See Other -> 메서드가 GET으로 변경
처음 302 스펙의 의도는 HTTP 메서드를 유지하는 것이었지만
웹브라우저들이 대부분 GET으로 바꾸어버렸다. ( 일부는 다르게 동작한다)
그래서 모호한 302 를 대신하는 307과 303이 등장했다.
현실적으로 307과 303을 권장하지만 많은 어플리케이션 라이브러리들이 302를 기본값으로 사용한다
자동 리다이렉션 시 GET으로 변해도 되면 그냥 302 사용해도 큰 문제 없다.
4xx ( Client Error )
클라이언트 요청에 잘못된 문법등으로 서버가 요청을 수행할 수 없음
오류의 원인 클라이언트에 있음
클라이언트가 이미 잘못된 요청 데이터를 보내고 있기 때문에 재시도 시 실패
400 Bad Request
클라이언트가 잘못된 요청을 하여 서버가 요청을 처리할 수 없음
- 요청 구문, 메세지 등 오류
- 클라이언트는 요청 내용을 다시 검토하고 보내야한다
- ex) 요청 파라미터 잘못되거나, API 스펙이 맞지 않을 때
401 Unauthorized
- 클라이언트가 해당 리소스에 대한 인증이 필요함
- 인증(Authentication) 되지 않음
- 401 오류 발생 시 WWW-Authenticate 헤더와 함께 인증 방법을 설명
인증 (Authentication) : 본인이 누구인지 확인 (로그인)
인가 (Authorization) : 권한부여 (Admin 권한처럼 특정 리소스에 접근할 수있는 권한, 인증이 있어야 인가가 있음)
401 오류 메세지가 Unauthorized 이지만 인증되지 않음이란 의미를 가져 명명이 아쉬움
403 Fobidden
- 서버가 요청을 이해했지만 승인을 거부함
- 주로 인증 자격은 있지만, 접근 권한이 불충분할 경우
- ex) 어드민 등급이 아닌 사용자가 로그인은 했지만 어드민 등급의 리소스에 접근하는 경우
404 Not Found
- 요청 리소스가 서버에 없을 경우
- 클라이언트가 권한이 부족한 리소스에 접근 시 해당 리소스 숨기고 싶을 경우
5xx (Server Error)
- 서버문제로 오류발생
- 서버에 문제가 있기 떄문에 재시도 하면 성공할 수 있음
500 Internal Server Error
- 서버 내부 문제로 오류 발생
- 애매하면 500 오류
503 Service Unavailable
- 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음
- Retry-After 헤더 필드로 얼마뒤에 복구되는지 보낼 수도 있음
HTTP 일반헤더
HTTP 헤더
header-field = filed-name ":" OWS field-value OWS (OWS : 띄어쓰기 허용)
HTTP 헤더의 용도
HTTP 전송에 필요한 모든 부가정보
ex) 메세지 바디의 내용, 메세지 바디의 크기, 압축, 인증, 요청 클라이언트, 서버 정보, 캐시 관리 정보
표준 헤더가 너무 많다
필요 시 임의의 헤더 추가 가능하다.
과거의 HTTP RFC2616 (폐기됨)
Http 헤더
- General 헤더 : 메세지 전체에 적용되는 정보
- Request 헤더 : 요청 정보
- Response 헤더 : 응답 정보
- Entity 헤더 : 엔티티 바디 정보
HTTP BODY
- 메시지 본문 (message body)은 엔티티 본문(entity body)을 전달하는데 사용
- 엔티티 본문은 엔티티 요청이나 응답에서 전달할 실제 데이터
- 엔티티 헤더는 엔티티 본문의 데이터를 해석할 수 있는 정보 제공 ( 데이터 유형 데이터 길이 압축 정보 등 )
현재의 HTTP RFC723x 변화
과거 Entity -> 현재 Representation
Representation = representation Metadata + Representation Data
표현 = 표현 메타데이터 + 표현 데이터
메세지 본문을 통해 데이터를 전달
메세지 본문 = 페이로드
표현은 요청이나 응답에서 전달할 실제 데이터
표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공 (데이터 유형, 데이터 길이, 압축정보)
표현
Content-Type : 표현 데이터의 형식
미디어 타입, 문자 인코딩
Content-Encoding : 표현 데이터의 압축 방식
표현 데이터를 압축하기 위해 사용
데이터를 전달하는 곳에서 압축 후 인코딩 헤더 추가
데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축 해제
Content-Language : 표현 데이터의 자연 언어
표현 데이터의 자연 언어를 표현
Content-Length : 표현 데이터의 길이
바이트 단위
Transfer-Encoding(전송 코딩)헤더를 사용하면 Content-Length를 사용하면 안됨
Transfer-Encoding(전송 코딩)헤더가 "chunked" 방식이라면
컨텐츠 길이를 미리 알지 못해도 브라우저는 청크를 받으면서 실시간으로 렌더링할 수 있다.
Transfer-Encoding이 Content-Length 헤더와 함께 사용되면 Content-Length가 무시되어 버릴 수 있기 때문이다.
Transfer-Encoding이 지정되어 있으면 데이터는 청크 형식으로 전송되기 때문에 콘텐츠의 실제 길이를 알 수 없게 됩니다. 따라서 Content-Length를 사용하여 명시적으로 데이터의 크기를 지정하는 것은 무의미해진다.
협상 (콘텐츠 네고시에이션)
- 클라이언트가 선호하는 표현 요청
- 요청시에만 사용
Accept : 클라이언트가 선호하는 미디어 타입 전달
Accept-Charset : 클라이언트가 선호하는 문자 인코딩
Accept-Encoding : 클라이언트가 선호하는 압축 인코딩
Accept-Language : 클라이언트가 선호하는 자연 언어
협상과 우선순위 ( Quality Values(q) )
0~1 , 클수록 높은 우선순위
생략 시 1
예시 )
GET /event
Accept-Language: ko-KR;ko;q=0.9,en-US;q=0.8;en;q=0.7
전송방식
- Transfer-Encoding
- Range, Content-Range
일반정보
From : 유저 에이전트의 이메일 정보
Referer : 이전 웹 페이지 주소
User-Agent : 유저 에이전트 어플리케이션 정보
Server: 요청을 처리하는 오리진 서버의 소프트웨어 정보
Date : 메세지가 생성된 날짜
Referer (이전 웹페이지 주소)
유입 경로 분석 가능
요청에서 사용
특별한 정보
Host : 요청한 호스트 정보
Location : 페이지 리다이렉션
Allow : 허용 가능한 HTTP 메서드
Retry-After : 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
Host 요청한 도메인 정보
요청에서 사용
필수
하나의 서버가 여러개의 도메인을 처리해야 하는 경우
Location 페이지 리다이렉션
웹 페이지는 3xx 응답의 결과에 Location 헤더가 있으면, Location위치로 자동 이동( 리다이렉트 )
응답코드 3xx 에서 설명
201 Created : Location 값은 요청에 의해 생성된 리소스 URI
3xx Redirection : Location 값은 요청을 자동으로 리다이렉션 하기 위한 대상 리소스를 가리킴
Allow 허용 가능한 HTTP 메서드
405 Method Not Allowed 에서 응답에 포함해야함
Allow : GET, HEAD, PUT
Retry-After 유저가 다음 요청을 하기까지 기다려야 하는 시간
유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
503 Service Unavailable : 서비스가 언제까지 불능인지 제공 가능
인증
- Authorization : 클라이언트 인증정보를 서버에 전달
- WWW-Authenticate : 리소스 접근 시 필요한 인증 방법 정의
쿠키
- Set-Cookie: 서버에서 클라이언트로 쿠키 전달 (응답)
- Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청 시 서버로 전달
Stateless
HTTP는 무상태 (Stateless) 프로토콜이다.
클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어진다
클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다
클라이언트와 서버는 서로 상태를 유지하지 않는다.
해당 방식으로 작동하게 된다면
모든 요청에 정보를 담게 된다.
모든요청에 특정 정보가 포함되도록 개발해야되는 번거로움이 생긴다.
쿠키 저장소에 저장된 쿠키는 필요 시 마다 재사용 되며 특정 유효 기간까지 유효하다.
쿠키의 사용처는 사용자 로그인 세션관리 , 광고정보 트래킹이 있다.
쿠키의 정보는 항상 서버에 전송되며 네트워크 추가 트래픽을 유발하기때문에 최소 정보만 사용한다.
서버에 전송하지 않고 웹 브라우저 내부에 저장하고 싶으면 localStorage, sessionStorage 쓰면 된다.
보안에 민감한 데이터는 저장하면 안된다.
쿠키의 생명주기
expires : 만료일이 되면 쿠키 삭제
Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT
max-age : 0이나 음수를 지정하면 쿠키 삭제
Set-Cookie: max-age=3600 (3600초)
캐시가 없을 때
- 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운받아야한다.
- 인터넷 네트워크는 느리고 비싸다
- 브라우저 로딩 속도가 느리다
- 느린 사용자 경험
캐시를 적용하고 나면
캐시 덕분에 이미 요청이 있어서 캐시 저장소에 리소스가 존재하면 캐시의 유효기간동안 네트워크를 사용하지 않아도 된다.
브라우저 로딩속도도 빠르다.
캐시의 시간이 초과하면, 서버를 통해 데이터를 다시 조회하고 캐시를 갱신한다.
이때 다시 네트워크 다운로드가 발생한다.
캐시 유효시간 초과
캐시 유효시간이 초과해서 서버에 다시 요청하면 다음 두가지 상황이 발생한다.
1. 서버에서 기존데이터를 변경함
2. 서버에서 기존데이터를 변경하지 않음
캐시 만료후에도 서버에서 데이터를 변경하지 않는 경우
생각해봄녀 데이터를 전송하는 대신에 기존에 캐시를 재사용이 가능할 수 있다.
단 , 클라이언트와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법이 필요하다.
이럴때 검증헤더를 사용한다.
캐시 유효 시간이 초과해도 서버의 데이터가 갱신되지 않았으면
304 Not Modified + 헤더 메타 정보만 응답한다
클라이언트는 서버가 보낸 응답 헤더로 캐시의 메타 정보를 갱신한다.
클라이언트는 캐시에 저장되어 있는 데이터를 활용한다.
검증헤더
검증헤더는 Last-Modified , ETag 가 있다.
조건부 요청헤더
- If-Modified-Since : Last-Modified 사용
- If-None-Match : ETag 사용
조건이 만족하면 200 ok
조건이 만족하지 않으면 304 Not Modified
If-Modified-Since : Last-Modified의 단점
1초 미만으로 캐시 조정 불가
날짜 기반 로직
데이터를 수정해서 날짜가 다르지만, 같은데이터를 수정해서 데이터 결과가 같을 경우
ETag ( Entity Tag )
캐시용 데이터에 고유한 이름을 달아둔다.
데이터가 변경되면 이 이름을 바꾸어 변경한다. (Hash 다시 생성)
단순히 ETag 보내서 같으면 데이터 유지 , 다르면 다시 받으면 된다.
이렇게 되는 경우
캐시 제어 로직을 서버에서 완전히 관리 할 수 있다.
클라이언트는 단순히 이 값을 서버에 제공해주기만 하면 된다.
캐시 제어 헤더
- Cache-Control : 캐시 제어
- Pragma : 캐시 제어 ( 하위 호환 )
- Expires : 캐시 유효 기간 ( 하위 호환)
Cache-Control: max-age 캐시 유효 기간, 초 단위
Cache-Control: no-cache 데이터 캐시 가능, 원 서버에 검증하고 사용
Cache-Control: no-store 민감한 정보가 있으므로 저장하면 안됨
프록시 캐시
캐시무효화
확실한 캐시 무효화 응답
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard
'스터디 > 2023_스프링부트' 카테고리의 다른 글
[study] 스프링MVC 정리 2 (0) | 2023.08.01 |
---|---|
[study] 스프링MVC 정리 1 (0) | 2023.07.24 |
[study]자바의정석 11~14 chapter (0) | 2023.07.18 |
[study] 자바의 정석 - chapter 6~9 (0) | 2023.07.09 |
[study] http 멱등성 알아보자 (0) | 2023.07.03 |