모든 개발자를 위한 HTTP 웹 기본 지식 (김영한)
사전 네트워크 기본 학습
인터넷 통신
복잡한 인터넷망 (수많은 복잡한 상황, 어떻게 목적지에 도착할까?)
IP (Internet Protocol)
인터넷 계층. IP 주소에 패킷 단위(규약, 규칙)로 데이터 전달
비연결성(불능, 대상x), 비신뢰성(패킷 소실, 전달순서문제), 같은 IP 구분
TCP
전송 제어 프로토콜, 3way handshake(접속 요청-요청수락-데이터 전송 가능)
데이터 전달 보장, 패킷 순서 보장
UDP
사용자 데이터그램 프로토콜
↔ TCP (연결 x, 전달 x, 순서x, 단순 빠름)
PORT
출발지 PORT, 목적지 PORT - TCP/IP 패킷 정보, 전송 데이터
같은 IP 내에서 프로세스 구분0 ~ 65535 할당 가능
0 ~ 1023 : 사용 x
FTP : 20,21
TELNET : 23
HTTP : 80
HTTP : 443같은 IP 안에서 동작하는 애플리케이션 구분하기 위해 사용
(IP = 아파트, PORT = 몇동 몇호)
DNS
IP는 기억하기 어렵고 변경될 수 있음 (고정/변동)
도메인 네임 시스템 (전화번호부, 도메인명을 IP 주소로 변환)
URI
Uniform Resource Identifier
리소스(자원)를 식별하는 통합된 방법
- URL : Uniform Resource Locator, 리소스가 이 위치에 있어요
- URN : Uniform Resource Name, 리소스의 이름을 부여
- 위치는 변할 수 있지만 이름 변하지 x
URL
scheme://[userinfo@]host[:port][/path][>query][#fragment]
프로토콜://호스트명:포트번호/경로/쿼리파라미터(쿼리스트링)
자원접근약속://도메인명orIP주소:포트번호는생략도가능/리소스계층구조/?key=value형태ex) https://www.google.com:443/search?q=hello&hl=ko
- 쿼리 파라미터 : 웹서버에 제공하는 파라미터 (string)
웹 브라우저 요청 흐름
URL을 호출했을 때 실제 웹 브라우저에서 네트워크에서 어떻게 패킷을 만들어서 어떻게 흘러가고 서버에 도착하고 응답을 주는지 웹 브라우저의 요청에 전체 흐름에 대해서 살펴보자
DNS 조회 > HTTP 요청 메세지 생성 > 소켓 라이브러리를 통해 전달 > TCP/IP 패킷 생성, HTTP 메시지 포함 > 응답 패킷 전달 > 도착 > 웹 브라우저 HTML 렌더링
모든 것이 HTTP
HyperText Transfer Protocol
HTML, TEXT, Image, 음성, 영상, 파일, JSON, XML(API) 등등 모든 형태 데이터 전송 가능HTTP의 역사
HTTP/1.1 1997년 : 가장 많이 사용, 우리에게 가장 중요한 버전 (대부분이 다 들어있음)
확인 : 크롬 개발자도구 F12 > Network > ProtocolHTTP의 특징
- 클라이언트 서버 구조
- 무상태 프로토콜(Stateless), 비연결성
- HTTP 메시지
- 단순함, 확장 가능
클라이언트 서버 구조
Request - Response
클라이언트와 서버를 개념적을 분리
서버에 비즈니스 로직을 밀어넣는다
클라이언트에는 UI, 사용성 집중
각각 독립적으로 진화
Stateful, Stateless
무상태 프로토콜
장점 : scale-out (확장성)
단점 : 클라이언트가 추가 데이터 전송Stateful - 상태유지 (항상 같은 서버 유지)
Stateless - 서버가 클라이언트의 상태를 보존하지 않는다 (중계서버 有, 상태 보관 x, 아무 서버나 호출해도 된다)무상태는 클라이언트 요청이 증가해도 서버 대거 투입 가능 (무한한 서버 증설 가능)
무상태의 한계 : 단순 화면이나 서비스에는 필요 x, 로그인 - 브라우저 쿠키와 서버 세션 활용, 데이터량웹 어플리케이션을 설계할 때는 최대한 무상태로 설계한다.
비연결성(connectionless)
HTTP는 기본이 연결 유지 x
서버 자원 가용성, 효율적 사용 (많이 사용해도 실제 동시에 처리하는 요청은 매우 적음)
TCP/IP 연결 새로 맺어야 함 (수많은 리소스들 함께 로드)
지속 연결(Persistent Connections)서버 개발자들이 어려워하는 업무
같은 시간에 딱 맞추어 발생하는 대용량 트래픽 (수만명 동시 요청)
HTTP 메시지
시작 라인 - 헤더 -공백라인 (CRLF) - 메시지 바디
매우 단순하지만 확장 가능
HTTP API를 만들어보자
회원 정보 관리 API를 만들어라 어떻게 하지..? 좋은 URI 설계는 뭘까?
가장 중요한 것은
리소스 식별
URI는 리소스만 식별, 행위(메서드)를 분리리소스의 의미가 뭘까?
회원이라는 개념 자체가 바로 리소스
리소스를 어떻게 식별하는 게 좋을까?
회원이라는 리소스만 식별 > 회원 리소스를 URL에 매핑
GET
리소스 조회
서버에 전달하고 싶은 데이터를 쿼리를 통해서 전달
POST
요청 데이터 처리, 주로 등록에 사용
메시지 바디를 통해 서버로 요청 데이터 전달 (신규 리소스 등록, 프로세스 처리)
PUT
리소스를 대체 - 해당 리소스가 없으면 생성
클라이언트가 리소스를 식별 (리소스 위치를 알고 URL 지정)
PATCH
리소스 부분 변경
DELETE
리소스 삭제
HTTP 메서드 속성
안전 : 호출해도 리소스 변경 x (장애 시 해당 리소스만 고려)
멱등 : 한 번 호출하든 두 번 호출하든 여러 번 호출하든 결과과 똑같다 (외부 요인으로 중간에 변경될 수 있음)
캐시가능 : 응답 결과 캐시해서 사용해도 되나?
클라이언트에서 서버로 데이터 전송
데이터 전달 방식
1) 쿼리 파라미터를 통한 데이터 전송 : GET
2) 메시지 바디를 통한 데이터 전송 : POST, PUT, PATCH1) 정적 데이터 조회
이미지, 정적 텍스트 문서 (단순 회)
2) 동적 데이터 조회
검색, 게시판 정렬 필터 (쿼리 파라미터 기반으로 필터링 후 결과 동적 생성)
3) HTML Form을 통한 데이터 전송
회원가입, 주문, 데이터 변경
4) HTTP API를 통한 데이터 전송
회원가입, 주문, 데이터 변경
서버to서버 : 백엔드 시스템 통신
앱 클라이언트 : iOS, AOS
웹 클라이언트 : AJAX, SPA
POST, PUT, PATCH, GET, Content-Type 등
HTTP API 설계 예시
- 문서
단일 개념 (파일 하나, 객체 인스턴스, 데이터베이스 row) ex) /files/star.jpg- 컬렉션
POST 기반 등록 ex) 회원 관리 API 제공 /members
서버가 관리하는 리소스 디렉토리- 스토어
PUT 기반 등록 ex) 정적 컨텐츠 관리, 원격 파일 관리 /files
클라이언트가 관리하는 리소스 저장소- HTML FORM 사용
GET, POST만 지원 ex) 웹 페이지 회원 관리
컨트롤 URI : 동사로 된 리소스 경로 ex) /members/{id}/delete
상태코드 소개
클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능
만약 모르는 상태 코드가 나타나면?
1xx
(Informational)
요청이 수신되어 처리중2xx
(Successful)
요청 정상 처라3xx
(Redirection)
요청 완료하려면 추가 행동 필요4xx
(Client Error)
클라이언트 오류, 잘못된 문법 등으로 서버가 요청 수행할 수 없음5xx
(Server Error)
서버 오류, 서버가 정상 요청 처리하지 못함
2xx - 성공
200 ok : 요청 성공
201 Created : 요청 성공해서 새로운 리소스가 생성됨
202 Accepted : 요청 접수됐으나 처리가 완료되지 않음
204 No Content : 서버가 요청 성공 수행했으나 응답 페이로드 본문에 보낼 데이터가 없음 (저장 버튼)
3xx - 리다이렉션
- 요청을 완료하기 위해 유저 에이전트의 추가 조치 필요
- 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동 (Redirect)
300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
307 Temporary Redirect
308 Permanent Redirect종류
- 영구 리다이렉션 : 특정 리소스의 URI가 영구적으로 이동 (301, 308)
- 일시 리다이렉션 : 일시적인 변경 (302, 307, 303)
ex) POST 주문 후에 웹브라우저 새로고침? 새로고침하면 다시 요청 (중복 주문이 될 수 있다)
=> 현실적으로 대다수 애플리케이션 라이브러리들이 302를 기본값으로 사용- 특수 리다이렉션 : 결과 대신 캐시 사용 (300, 304), 클라이언트는 로컬PC에 저장된 캐시 재사용
4xx - 클라이언트 오류
클라이언트의 요청에 잘못된 문법 등으로 서버가 요청을 수행할 수 없음
오류 원인은 클라이언트
재시도해도 실패
- 400 Bad Request : 요청 구문, 파라미터, API스펙, 메시지 오류
- 401 Unauthorized : 클라이언트가 해당 리소스에 대한 인증 필요 (인증, 인가)
- 403 Forbidden : 서버가 요청을 이해했지만 승인 거부 (등급 아닌 사용자가 리소스에 접근한 경우)
- 404 Not Found : 요청 리소스가 서버에 없음, 권한 부족한 리소스 접근 시 리소스 숨기고 싶음
5xx - 서버 오류
서버의 문제
에 의해 서버 응답을 수행할 수 없음
서버에 문제가 있기 때문에 재시도하면 성공할 수도 있음 (복구)
- 503 Service Unavailable : 서버가 일시적 과부하 또는 예정된 작업으로 잠시 요청 처리 X, Retry-After 헤어 필드로 얼마뒤에 복구되는지 보낼 수도 있음
HTTP 헤더 개요
- HTTP 전송에 필요한 모든 부가정보
ex) 메세지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트, 서버 정보, 캐시 관리 정보 ...- header-field = field-name ":" OWS field-value OWS (OWS : 띄어쓰기 허용)
- field-name은 대소문자 구분 없음
- General, Request, Response, Entity
GET /search?q=hello&hl=ko HTTP/1.1 Host: www.google.com HTTP/1.1 200 OK Content-Type: text/html;charset=UTF-8 Content-Length: 3423 <html> <body>...</body> </html>
HTTP BODY
메시지 본문은 엔티티 본문 전달하는데 사용
표현은 요청이나 응답에서 전달할 실제 데이터
표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공 (html, json, 데이터 길이, 압축 정보 등등)
표현
html, json
- Content-Type : 표현 데이터의 형식
- Content-Encoding : 표현 데이터의 압축 방식
- Content-Language : 표현 데이터의 자연 언어
- Content-Length : 표현 데이터의 길이
HTTP/1.1 200 OK Content-Type: text/html;charset=UTF-8 Content-Language: ko Content-Length: 521 <html> 안녕하세요. </html>
콘텐츠 협상
클라이언트가 선호하는 표현 요청
- Accept : 클라이언트가 선호하는 미디어 타입 전달
- Accept-Charset : 클라이언트가 선호하는 문자 인코딩
- Accept-Encoding : 클라이언트가 선호하는 압축 인코딩
- Accept-Language : 클라이언트가 선호하는 자연 연어
협상 우선순위
Quality Values(q) 값 사용, 0~1, 클수록 높은 우선순위 ex) 다중언어
구체적인 것이 우선GET /event Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
전송 방식
단순 전송, 압축 전송, 분할 전송, 범위 전송
일반 정보
- From : 유저 에이전트의 이메일 정보 ex) 검색엔진 크롤러
- Referer : 이전 웹페이지 주소 ex) 현재 요청된 페이지의 이전 웹페이지 주소 (Request Header)
- User-Agent : 유저 에이전트 애플리케이션 정보 (클라이언트의 애플리케이션 정보 ex) 웹브라우저 정보, 통계 정보 등)
=> 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능 (요청)user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36
- Server : 요청을 처리하는 origin 서버의 소프트웨어 정보
Apache/2.2.22 (Debian), nginx (응답)- Date : 메시지가 생성된 날짜
특별한 정보
- Host : 요청한 호스트 정보(도메인), 필수, 하나의 서버가 여러 도메인 처리, 여러 IP
ex) 가상호스트를 통해 여러 도메인을 한번에 처리할 수 있는 서버 (실제 애플리케이션 여러개 구동가능)- Location : 페이지 리다이렉션
- Allow : 허용 가능한 HTTP 메서드
- Retry-After : 유저 에이전트가 다음 요청을 하기 까지 기다려야 하는 시간
인증
- Authorization : 클라이언트 인증 정보를 서버에 전달
- WWW-Authenticate : 리소스 접근 시 필요한 인증 방법 정의
쿠키
- Set-Cookie : 서버에서 클라이언트로 쿠키 전달(응답)
- Cookie : 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청 시 서버로 전달
- 무상태(Stateless) 프로토콜 상태 로그인 페이지 접근
- 대안 : 모든 요청에 사용자 정보 포함? (모든 요청에 사용자 정보가 포함되도록 개발해야 하는 문제)
- 쿠키의 주 사용처 : 사용자 로그인 세션 관리
- 쿠키 정보는 항상 서버에 전송됨 (최소 정보만 사용 - 세션 id, 인증 토큰)
- 서버에 전송하지 않고 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹스토리지(로컬스토리지, 세션스토리지) 참고
주의 : 보안에 민감한 데이터는 저장하면 안됨
(주민번호, 신용카드 번호 등)more
- 쿠키 생명주기 (expires, max-age) : 만료일이 되면 쿠키 삭제
- 쿠키 도메인 지정 : 명시-기준도메인+서브도메인, 생략-현재 문서기준에만 적용
- 쿠키 경로 : 이 경로를 포함한 하위 경로 페이지만 쿠키 접근 path=/home
- 쿠키 보안 : Secure(HTTPS), HttpOnly(HTTP 전송에만, JS 접근불가), SameSite (도메인같은경우에만)
캐시 기본 동작
캐시가 없을 때
- 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운로드 받아야 한다
- 인터넷 네트워크는 매우 느리고 비싸다
- 브라우저 로딩 속도가 느리다
- 느린 사용자 경험
캐시 적용
- 캐시 덕분에 캐시 가능 시간동안 네트워크를 사용하지 않아도 된다.
- 비싼 네트워크 사용량을 줄일 수 있다
- 브라우저 로딩 속도가 매우 빠르다
- 빠른 사용자 경험
캐시 시간 초과
- 캐시 유효시간 초과 시 서버를 통해 데이터 다시 조회하고 캐시 갱신
- 이때 다시 네트워크 다운로드가 발생
검증 헤더와 조건부 요청
캐시 시간 초과
캐시 유효 시간이 초과해서 서버에 다시 요청하면 다음 2가지 상황 발생
1) 서버에서 기존 데이터를 변경함
2) 서버에서 기존 데이터를 변경하지 않음
- 캐시 만료 후에도 서버에서 데이터를 변경하지 않는다면 데이터 전송 대신 저장해둔 캐시를 재사용 가능
- 단, 클라이언트의 데이터와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법 필요
정리
- 캐시 유효 시간 초과해도 서버의 데이터가 갱신되지 않으면 304 Not Modified+헤더메타정보만 응답 (바디x)
- 클라이언트는 서버가 보낸 응답 헤더 정보로 캐시의 메타 정보 갱신
- 클라이언트는 캐시에 저장되어 있는 데이터 재활용
- 결과적으로 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드
검증 헤더
- 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
- Last-Modified, ETage
조건부 요청 헤더
- 검증 헤더로 조건에 따른 분기
- If-Modified-Since: Last-Modified 사용
- If-None-Match: ETag 사용
- 조건이 만족하면 200 OK
- 조건이 만족하지 않으면 304 Not Modified
단점
- 1초 미만(0.x초) 단위로 캐시 조정 불가능
- 날짜 기반 로직 사용
- 데이터 수정해서 날짜가 다르지만 같은 데이터 수정 시 데이터 결과가 똑같은 경우
- 서버에서 별도 캐시 로직 관리하고 싶은 경우 (스페이스, 주석 같은 영향낮은 변경에서 캐시 유지)
ETage(Entity Tag)
- 임의의 고유한 버전 이름
- 캐시 제어 로직을 서버에서 완전히 관리
캐시와 조건부 요청 헤더
- Cache-Control
ㄴ max-age : 캐시 제어
ㄴ no-cache : 캐시 유효시간
ㄴ no-store : origin 서버에 검증하고 사용, 민감한 정보있으면 저장하면 안됨- Pragma : 캐시 제어(하위호환)
- Expires : 캐시 유효기간(하위호환)
프록시 캐시
- 원 서버 직접 접근 : origin 서버
- 프록시 캐시 서버 : 중간에 있는 서버
캐시 무효화
- 확실한 캐시 무효화 응답
Cache-Control: no-cache, no-store, must-revalidate
Pragma:no-cache
⭐️ 다음으로
- 실무에 꼭 필요한 HTTP 핵심 학습 완료 (단 정확하지 않은 자료가 많으므로 항상 의심)
- HTTP에 대해서 더 깊이있게 학습 (HTTP 스펙, HTTP 완벽 가이드 책)
1) 백엔드 개발자
Spring, 웹 MVC, JSP, PHP, ASP.NET, Node.js, 파이썬 장고, Ruby on Rails와 같은 웹 프레임워크나 기술들을 사용하는데 이러한 웹 기술들은 모두 HTTP 기반으로 구현되어 있음 인지
2) 처음 웹 기술을 공부하는 개발자
HTTP 기본 이해를 통해 웹 프레임워크가 제공하는 기술들을 깊이 이해하는 것이 좋음
3) 실무에서 웹 기술을 사용하는 개발자
API URI, 메서드 선택 등등 HTTP와 관련된 설계시 명확한 기준안에서 선택
💬 오늘 아침에 회사에서 서버 관련 문제가 있던 거 같았는데(분주한 개발자들) 문득 생각나서 뒤늦게 수강..
김영한 님 😀 강의 사놓고 이제야 집중해서 다 들었다.. 나는 기본 이해 중 😁
💬 마지막에는 자바 백엔드 개발자에 대한 조언이었지만 이 부분이 참 인상적이어서 기록.
항상 준비
하면서도 순발력
이 있으면 좋을 것 같다(희망사항)
학자형 코스 vs 야생형 코스
학자형 코스 : 이론을 먼저 차근차근 쌓아올린 다음에 실무 활용으로 넘어가는 방식
야생형 코스 : 일단 실무에서 어떤 기술을 어떤 식으로 활용하는지, 깊이가 부족해도 일단 경험해본 다음 필요에 의해서 이론 기술들을 공부하는 방식