DRF 1강 - HTTP와 웹 동작 방식
0. 프론트와 백엔드의 분리
현재까지는 장고 템플릿을 이용해 프론트와 백의 구분이 모호하게 진행하였다. 템플릿에서 다루는 데이터는 모두 views.py에서 받아오는 데이터였기 때문이다. 서버에 요청을 보낸 뒤 페이지 자체를 새로고침하여 html, css, js등을 모두 다시 렌더링해야하는 불편함이 존재한다.
Ajax(비동기 자바스크립트와 XML)의 등장으로 전체를 다시 렌더링할 필요없이 일부만 다시 업데이트 요청할 수 있게되었다.
앵귤러, 리액트 등 프론트에도 이러한 방식과 함께 사용할 수 있는 유용한 도구가 발전하며 점차 프론트와 백의 분리가 일어나게 된다.
그러므로 이제부터 DRF를 이용해 백엔드에서 API와 DB 등을 구성하는 것에 집중한다.
1. 포스트맨 사용해보기
포스트맨을 통해 프론트 구현 없이도 편리하게 요청을 보낼 수 있다.
포스트맨을 설치하고 아무 웹 서버에 get요청을 보내보자.
헤더에 알아서 무언갈 채워 보냈고, 응답으로 html이 오는 것을 볼 수 있다.
왼쪽 아래 콘솔을 보면 request 헤더에 어떤 것들을 채워보냈는지 볼 수 있다.
브라우저는 요청을 보낼 때 알아서 헤더를 채워서 보내고, 응답으로 오는 html을 시각화하는 기능을한다.
개발자 도구를 통해 살펴보면 리퀘스트와 body의 내용을 확인해볼 수 있다.
2. HTTP아래 Layer의 동작
웹 브라우저의 흐름
- DNS를 조회해 접속할 IP를 받아온다.
- HTTP 요청 메시지를 작성한다.
- Socket 라이브러리를 통해 전달한다.
- HTTP를 포함한 TCP/IP 헤더를 작성해 네트워크에 보낸다.IP지정한 IP주소로 노드들을 거쳐서 송신한다. source IP와 destination IP를 작성한다.
IP만으로는 받을 대상이 없거나, 중간에 패킷(전송단위)가 손실되거나, 순서가 뒤섞일 수도 있고 같은 IP를 사용하는 프로세스가 여러개라면 문제가 생긴다.
TCP vs UDP
TCP는 IP보다 상위 레벨로 ip를 보완한다. 출발-목적 port 정보를 가지고있다. 전송제어(전송 보장), 순서 보장, 검증 기능 등 제공.
신뢰 가능해 대부분 사용.
3 Way Handshake
TCP가 논리적 연결을 성립하기 위해 하는 절차.
- client -> server : SYN
- server -> client : SYN + ACK
- client -> server : ACK + data
UDP는 TCP에 기능이 거의 없고 IP에 포트와 체크섬만 추가된다.
어플리케이션에서 추가작업이 필요하지만 빠르다.
PORT
같은 IP내에서 프로세스를 구분해준다.
DNS
IP주소와 도메인 주소(URI)를 연결해주는 주소록 서버이다.
URI?
naver.com:80
Uniform Resource Identifier의 줄임말로, 계층적 구조로 이루어진다. 포트 생략시 http는 80, https는 443.
HTTP
하이퍼텍스트를 HTML형태로 주고받기 위해 만든 규약(protocol)으로 현재는 모든 데이터를 전송가능하다.
크롬 검사창에서 network 탭을 보면 현재 http 버전을 볼 수 있다.
특징1: 클라이언트-서버 구조
request-response 구조이기도 하다.
클라이언트는 request를 보내고 response를 기다린다.
분리가 중요한 이유
- 데이터와 로직을 서버에, ui는 클라이언트에 넣으면 독립적으로 운용,개발 가능
- 클라이언트가 무엇이든 될 수 있다. (모바일, PC, 웹...)
- 트래픽 폭주시 서버만 대응해도 된다.특징2: Stateless서버가 클라이언트의 상태를 보존하지 않는다. 즉 누가 누군지 모른다. 연결은 지속되지 않는다. 이렇게 해서 응답 서버를 쉽게 바꿀 수 있다.
세션 로그인은 상태가 있다.(최소한의 사용)
특징3: 비연결성
연결을 유지하지 않고 최소한의 자원을 사용한다. 응답은 매우 빠르므로 동시처리하는 요청이 적고 서버 자원을 효율적으로 활용가능하다.
요청과 응답의 구조
메서드
필요한 동작 마다 API 주소를 여러개 만드는 것은 좋은 설계가 아니다. 주소(URI)는 리소스(회원정보 등) 식별이 주요 목적이다.
리소스에 하는 행위의 유형을 정한것이 '메소드' 라고 하는것이다.
이렇게 리소스와 행위를 분리하는 것이 RESTful API의 핵심이다.
메소드의 종류
- GET: 조회. 데이터는 쿼리 파라미터로 전달한다. 캐싱이 가능하므로 가능한 GET을 쓴다.
- POST: message body를 통해 서버로 요청 데이터를 전달하거나 프로세스를 처리해야하는 경우 사용.
JSON으로 조회 데이터를 넘길 때 get을 쓰기 힘들 때 쓰기도한다. - PUT: 대체/생성. 클라이언트가 URI를 지정해서 보내는 것이 POST와의 차이다.
- PATCH: 부분변경
- HEAD: 상태줄과 헤더만 반환. 이외엔 GET과 동일
메소드의 속성
- 안전: 리소스가 변경되지 않는다.
- 멱등: 반복해도 결과가 같다.(GET, PUT, DELETE) - POST는 중복발생
- 캐시가능: GET, HEAD
메소드의 데이터 전송
- 쿼리 파라미터
- GET. 검색, 정렬, 필터
- Massege Body
- POST, PUT ,PATCH. 가입, 주문, 리소스 등록등의 변경
Form
GET, POST만 지원하는 데이터 전송을 위한 태그.
entype 속성값(Content-Type)
- application/x-www-form-rulencoded
- Body에 쿼리파라미터처럼 실린다.
name=ChulSu&age=20
-
- 전송데이터는 url encoding처리
안녕 -> %EC%95%88%EB%85%95%0A
-
- multipart/form-data
- 파일을 같이 보낼때, 바이너리 데이터 보낼때 사용. 모든 문자를 인코딩 하지 않음을 명시한다.
- 다른 여러종류의 파일과 폼의 내용 함께 전송 가능
HTTP API를 통한 데이터 전송
- Content-Type: application/json
- 서버간 전송, 앱 클라이언트, 웹 클라이언트간 JSON형태로 전송(ajax)
- From 대신 JS를 이용한 통신
- POST, PUT, Patch 메시지 바디로 데이터 전송 가능
HTTP API 특징
- 클라이언트는 등록될 리소스의 URI를 알 수 없다.
- 서버가 리소스의 URI를 생성한다.
HTTP 상태 코드(응답)
- 1XX: 요청 처리중
- 2XX: 정상 처리
- 200: 정상
- 201: Created. header에 location을 추가해 새로운 리소스의 URI를 알려줄 수 있음
- 202: Acceptedd. 접수는 했다는 뜻
- 204: No Content. 저장만하고 화면 변화가 필요없을 때
- 3XX: 추가적인 행동이 필요하다.
브라우저는 3xx헤더에 location이 있으면 자동 리다이렉트함.- 영구 redirect: method와 body가 바뀌는 301, 308
- 일시 redirect: 일시적인 변경 (주문완료후 주문내역 이동 등)
- 302: redirect시 메소드는 GET, 본문제거
- 307: redirect시 메소드, 본문 유지
- PRG(POST,Redirect,Get)
POST로 주문 후 새로고침시 중복주문 가능하지만 완료시 302를 줘서 redirect시키면 새로고침해도 결과화면만 다시 요청한다.
- 4XX: 클라이언트 에러. 잘못된 문법, 클라이언트에 원인 존재
- 400: 요청 내용 다시 검토필요(API 스펙 확인)
- 401: 인증이 안됨(로그인안함)
- 403: 권한 없음(관리자아님)
- 404: 리소스가 없거나 숨기고 있음
- 5XX: 서버에러. 원인이 서버에 존재. 복구후 재시도시 성공가능
- 500: 서버 내부 문제
- 503: 서버 일시 과부하
HTTP Header
종류가 굉장히 많으며 필요에 따라 추가내용을 넣을 수도 있다.
- 필드네임(key)은 대소문자를 구분하지 않는다.
- HTTP 전송에 필요한 모든 부가정보를 포함하고 바디의 데이터를 해석할 수 있는 정보도 제공한다.
- 바디 내용, 크기
- 압축 방식
- 인증
- 요청한 클라이언트 정보
- 캐시 관리
대표적인 헤더들
- 표현: 리소스를 무엇으로 표현했는지에 대한 정보(html, xml, json)
- Content-Type: 형식
- Content-Encoding: 압축 방식(안한경우 포함)
- Content-Language: 언어
- Content-Length: 길이(바이트 단위). Trnasfer-Encoding 사용시 사용불가
- 컨텐트 협상(Accept-): 클라이언트가 선호하는 XX 에 대한내용
- 전송방식: 단순전송, 압축전송, 분할전송(Trnasfer-Encoding: chunked), 범위전송 등
- 일반: referer(유입경로 분석), user-agent(브라우저정보), server(서버의 sw 정보)...
- 특수정보:
- Host:요청한 호스트 정보(도메인) 필수. 한 서버에 여러 IP가 존재 가능하므로 반드시 있어야함.
- Allow: 허용가능한 메서드 정보
- 인증:
- Authoriation: 클라이언트의 인증정보 서버에 전달. 인증반식에 따라 들어가는 값이 달라짐.
- WWW-Authenticate: 리소스 접근시 필요한 인정 방법 정의.
리스폰스 시 401과 함께 사용. 어떻게 인증정보를 만들지에 대한 정보
- 쿠키
HTTP의 무상태 연결을 보완한다. 모든 요청과 링크에 사용자 정보를 포함해야한다는 점을 해결.- set-cookie: 리스폰스시 서버에서 클라이언트로 쿠키 전달. 만료기간/ 경로/ 도메인 설정가능
- Cookie: 클라이언트가 서버에서 받은 쿠키 저장후 요청시 서버로 전달
- 캐시
네트워크는 느리고 비싸다. 리소스를 아끼기 위해 응답결과를 브라우저가 저장해두고 이후 캐시로 부터 받아온다. 서버에서 데이터가 변경되거나 기존 데이터가 동일하면 유효기간을 초과하게되어 다시 정보를 서버로부터 받는다.- 검증 헤더 last-modified: 데이터 변경정보. 캐시 유효기간 늘릴 수 있음
- if-modified-since: 다시 보내야 하는지 판단가능. 304를 이용해서 캐시데이터를 쓴다.
- 캐시와 조건부 요청 헤더
- cache-control:
- max-age: 유효기간
- no-cache: 서버에서 검증하고 사용
- no-store: 최대한 빨리 삭제(민감정보)
- cache-control: