OSI 7 계층과 인터넷 프로토콜 스택의 4 계층
TCP의 특징은 가상 연결, 데이터 전달보증, 순서 보장이 있으며 소켓이 연결됐다 라는것은 사실은 물리적으로 진짜 연결된 것이 아닌 논리적으로만 연결된 것이다.
UDP의 특징은 IP와 같은데 + PORT, + 체크섬 정도만 추가된 단순하고 빠른 프로토콜이며 HTTP3에서 사용중이다.
HTTP의 특징은 비연결성, 클라이언트 서버 구조, 무상태가 있으며 Stateless 하기 때문에 서버 확장성이 높음(스케일 아웃)
HTTP 메서드의 속성
- 안전(Safe Methods): 호출해도 리소스를 변경하지 않는다. ➪ GET
- 멱등(Idempotent Methods): 몇번을 호출하든 결과가 똑같다. ➪ GET, PUT, DELETE
- 캐시가능(Cacheable Methods): 응답 겨로가 리소스를 캐시해서 사용해도 되는가? ➪ 실제로는 GET, HEAD정도만 캐시로 사용
API URI
- URI는 리소스만 식별!
- 리소스와 해당 리소스를 대상으로 하는 행위를 분리 (리소스: 회원 / 행위: 조회, 등록, 삭제, 변경)
- 리소스는 명사, 행위는 동사
- 리소스는 복수형
- 리소스만으로 안될 때는 + /(컨트롤 URI) 추가 ex) POST /orders/{orderId}/start-delivery
HTTP 상태코드
1xx (Infomational): 요청이 수신되어 처리중 (거의 사용 안됨)- 2xx (Successful): 요청 정상 처리 (200 OK, 201 Created 정도만 사용)
- 3xx (Redirection): 요청을 완료하여 추가 행동이 필요
- 영구 리다이렉션 (301, 308): 특정 리소스의 URI가 영구적으로 이동
- 예) /members -> /users
- 예) /event -> /new-event
- 301 Moved Permanently, 308 Permanent Redirect
- 결론: 301 대응으로 308이 등장 그러나 둘 다 실무에서 잘 사용하지 않음
- 일시 리다이렉션 (302, 307, 303): 일시적인 변경
- 302 Found -> GET으로 변할 수 있음
- 307 Temporary Redirect -> 메서드가 변하면 안됨
- 303 See Other -> 메서드가 GET으로 변경
- 처음 302 스펙의 의도는 HTTP 메서드를 유지하는 것 이였지만 웹 부라우저들이 대부분 GET으로 바꾸어버림
- 결론: 307, 303을 권장하지만 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용하므로 자동 리다이렉션시에 GET으로 변해도 되면 그냥 302를 사용해도 큰 문제 없음
- 특수 리다이렉션 (300, 304): 결과 대신 캐시를 사용
- 300 Multiple Choices: 안쓴다.
- 304 Not Modified
- 캐시를 목적으로 사용
- 클라이언트에게 리소스가 수정되지 않았음을 알려준다. 따라서 클라이언트는 로컬 PC에 저장된 캐시를 재사용한다.(캐시로 리다이렉트 한다.)
- 304 응답은 메시지 바디를 포함하면 안된다. (로컬 캐시를 사용해야 하므로)
- 조건부 GET, HEAD 요청시 사용
- 영구 리다이렉션 (301, 308): 특정 리소스의 URI가 영구적으로 이동
- 4xx (Client Error): 클라이언트 오류, 잘못된 문법등으로 서버가 요청을 수행할 수 없음
- 401 Unauthorized: 클라이언트가 해당 리소스에 대한 인증이 필요함
- 인증(Authentication): 본인이 누구인지 확인 (로그인)
- 인가(Authorization): 권한부여 (ADMIN, 인증이 있어야 인가가 있음)
- 오류 메시지가 Unauthorized 이지만 인증 되지 않음 (이름이 아쉬움)
- 403 Forbidden: 서버가 요청을 이해했지만 승인을 거부함
- 인증은 됐지만 인가가 안됨
- 예) 어드민 등급이 아닌 사용자가 로그인은 했지만, 어드민 등급의 리소스에 접근하는 경우
- 404 Not Found
- 요청 리소스가 서버에 없음
- 클라이언트가 권한이 부족한 리소스에 접근할 때 403을 사용해도 되지만 해당 리소스를 숨기고 싶을 때
- 401 Unauthorized: 클라이언트가 해당 리소스에 대한 인증이 필요함
- 5xx (Server Error): 서버 오류, 서버가 정상 요청을 처리하지 못함, 서버에 문제가 있기 때문에 재시도하면 성공할 수도 있음 (복구 되었거나 등등)
- 500 Internal Server Error
- 서버 내부 문제로 오류 발생
- 애매하면 500 오류
- 503 Service Unavailable: 서비스 이용 불가 (잘 사용 안하고 대부분 500)
- 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음
- Retry-After 헤더 필드로 얼마뒤에 복구되는지 보낼 수도 있음
- 500 Internal Server Error
표현 (표현 헤더는 요청, 응답 둘 다 사용)
- Content-Type: 표현 데이터의 형식 설명
- body에 들어가는 타입이 무엇인지
- 예) application/jso, image/png
- Content-Encoding: 표현 데이터 인코딩
- 표현 데이터를 압축하기 위해 사용
- 데이터를 전달하는 곳에서 합축 후 인코딩 헤더 추가
- 데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축 해제
- 예) gzip, deflate, identity
- Content-Language
- 표현 데이터의 자연 언어를 표현
- 예) ko, en, en-US
- Content-Length: 표현 데이터의 길이
- 바이트 단위
- Transfer-Encoding(전송 코딩)을 사용하면 Content-Length를 사용하면 안됨
협상(콘텐츠 네고시에이션): 클라이언트가 선호하는 표현 요청 (협상 헤더는 요청시에만 사용)
- Accept: 클라이언트가 선호하는 미디어 타입 전달 (구체적으로 작성한것이 우선순위가 높다.)
- Accept-Charset: 클라이언트가 선호하는 문자 인코딩
- Accept-Encoding: 클라이언트가 선호하는 압축 인코딩 (gzip 인코딩 같은거)
- Accept-Language: 클라이언트가 선호하는 자연 언어 (Quality Values로 우선순위를 정할 수 있다.)
전송 방식
- 단순 전송
- 압축 전송
- 분할 전송
- 범위 전송
일반 정보
- From: 유저 에이전트의 이메일 정보
- Referer: 이전 웹 페이지 주소
- User-Agent: 유저 에이전트 애플리케이션 정보 (요청에서 사용)
- Server: 요청을 처리하는 오리진 서버의 소프트웨어 정보 (응답에서 사용)
- Date: 메시지가 생성된 날짜 (응답에서 사용)
특별한 정보
- Host: 요청한 호스트 정보(도메인)
- 요청에서 사용, 필수
- 하나의 서버가 여러 도메인을 처리해야 할 때
- 하나의 IP 주소에 여러 도메인이 적용되어 있을 때
- Location: 페이지 리다이렉션
- 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)
- 201 (Created): Location 값은 요청에 의해 생성된 리소스 URI
- 3xx (Redirection): Location 값은 요청을 자동으로 리다이렉션 하기 위한 대상 리소스를 가리킴
- Allow: 허용 가능한 HTTP 메서드 (잘 사용 X)
- Retry-After: 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간 (잘 사용 X)
쿠키
- Set-Cookie: 서버에서 클라이언트로 쿠키 전달 (응답)
- Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달
- 사용처
- 사용자 로그인 세션 관리
- 광고 정보 트래킹
- 쿠키 정보는 항상 서버에 전송됨
- 네트워크 트래픽 추가 유발
- 최소한의 정보만 사용 (세션 id, 인증 토큰)
- 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 (클라이언트에 보관하고 있다가 필요할때만 보내거나 클라이언트 자바스크립트 로직에서만 쓰고싶을 때) 웹 스토리지 (localStorage, sessionStorage) 참고
Stateless
- HTTP는 무상태 프로토콜이다.
- 클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어진다.
- 클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다.
- 클라이언트와 서버는 서로 상태를 유지하지 않는다.