인프런 - 모든 개발자를 위한 HTTP 웹 기본 지식 학습 정리
https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard
*. 초급 수준의 기본적인 학습 정보는 생략함, 네트워크 URI/URL ETC
1. 비 연결성 (connectionless)
1) http 1.1 ,2, 3에 따라 지속 연결 방식이 달라진다.
1-1) http 지속 연결(Persistent Connections)란
- 기본적으로 TCP는 3 way handshake를 수행한다
- 초기 http는 매 연결(html 응답, 자바스크립트 응답, 이미지 응답)에 관련한 작업을 수행함
- http 버전 발전에 따라 이러한 연결 과정을 생략하고 버스트하게 전송하는 매커니즘 수행
- http3는 udp 프로토콜을 사용하여 더 간략하고 빠른 연결을 수행함
- 스펙은 http1.1 기준으로 봐야하고 http2, 3은 성능 부분이라 생각하면 됨
2. API URI 설계 : 리소스 식별, URI 계층 구조 활용
1) API 설계 예시
1-1) 회원 관리에 대한 API를 만드는 경우 자원(resource) 혹은 명사에 집중한다.
* Resource란 표현은 근래 Representation이라고 명칭을 바꿔 사용함
* 이상적인 API 설계는 실무에는 없다. 필요한 경우 컨트롤 URI를 사용한다
예) POST /orders{{orderid}/start-delivery
- 회원 목록 조회 /members
- 회원 조회 /members/{id}
- 회원 등록 /members/{id}
- 회원 수정 /members/{id}
- 회원 삭제 /members/{id}
3. HTTP 메서드 활용
1) HTTP 메서드의 속성
1-1) 요약표
2) 멱등 (Idempotent)
- f( f( x ) ) = f( x )
- 정의 : 한 번 호출을 하든 여러번 호출하든 결과가 똑같다.
1-1) 멱등 메서드
- GET : 항상 같은 결과가 조회된다
- PUT : 결과를 대체한다
- DELETE : 결과를 삭제한다
- POST : 멱등이 아니다! 예) 두 번 호출하면 같은 결제가 중복해서 발생할 수 있다
1-2) 멱등 활용
- 매번 동일한 결과를 수행, 동일한 데이터에 대해서 동일한 작업을 요청한다는 점을 이용
- 서버가 타임아웃 등으로 응답을 못주었을때, 클라이언트가 같은 요청을 다시 수행할 수 있음
- 자동 복구 메커니즘
3) 캐시가능 (Cacheable)
1-1) 응답 결과 리소스를 캐시해서 사용해도 되는가?
- GET, HEAD, POST, PATCH 캐시가능
- 실재로는 GET, HEAD 정도만 캐시로 사용
- POST, PATCH는 본문 내용까지 캐시 키로 고려해야 하는데 구현이 어려움
4) HTTP API 설계 예시
1-1) 요구사항
- HTTP API - 컬렉션
- 예) 회원 관리 API 제공
- HTTP API - 스토어
- PUT 기반 등록
- 예) 회원 관리 API 제공
- HTML FORM 사용
- 웹 페이지 회원 관리
- GET, POST만 지워
* 동일한 VALUE에 대한 API의 조회, 수정은 가능한 동일 URI로 제어함
이러한 구조는 에러 발생 및 상태 리프레쉬 작업에 복구가 용의함 (GET으로 전환)
- 예) 조회 /members - GET
- 예) 등록 /members - POST
1-2) 회원 관리 시스템 개발, API 설계 - POST 기반 등록
- 회원 목록 /members -> GET
- 회원 등록 /members -> POST
- 회원 조회 /members/{id} -> GET
- 회원 수정 /members/{id} -> PATCH, PUT, POST
- POST를 이용한 등록과의 차이는, 정확한 타겟(id,파일명 etc )의 유무
- 회원 삭제 /members/{id} -> DELETE
* 컬렉션이란? :
- 서버가 관리하는 리소스 디렉토리
- 서버가 리소스의 URI를 생성하고 관리
- 여기서 컬렉션은 /members
1-3) 파일 관리 시스템, API 설계 - PUT 기반 등록
- 파일 목록 /files -> GET
- 파일 조회 /files/{filename} -> GET
- 파일 등록 /files/{filename} -> PUT
- 클라이언트가 리소스 URI를 알고 있어야 함
- PUT /files/star.jpg
- 파일 삭제 /files/{filename} -> DELETE
- 파일 대량 등록 /files -> POST
* 스토어 :
- 클라이언트가 관리하는 리소스 저장소
- 클라이언트가 리소스의 URI를 알고 관리
- 여기서 스토어는 /files
1-4) HTML FORM 사용시
- HTML FROM은 GET, POST만 지원
- 컨트롤 URI
- GET, POST만 지원하므로 제약이 있음
- 이런 제약을 해결하기 위해 동사로 된 리소스 경로 사용
- POST의 /new, /edit, /delete등의 사용자가 제어하는 컨트롤 URI 사용
- HTTP 메서드로 해결하기 애매한 경우 사용(HTTP API 포함)
1-5) 참고하면 좋은 URI 설계 개념
- Reference : https://restfulapi.net/resource-naming/
- 문서 (document)
- 단일 개념(파일 하나, 객체 인스턴스, 데이터베이스 row)
- 예) /members/100, /files/star.jpg
- 컬렉션(collection)
- 서버가 관리하는 리스소 디렉터리
- 서버가 리소스의 URI를 생성하고 관리
- 예) /members
- 스토어(store)
- 클라이언트가 관리하는 자원 저장소
- 클라이언트가 리소스의 URI를 알고 관리
- 예) /files
- 컨트롤러(controller), 컨트롤 URI
- 문서, 컬렉션, 스토어로 해결하기 어려운 추가 프로세스 실행
- 동사를 직접 사용
- 예) /members/{id}/delete
4. HTTP 상태코드 소개
1) 상태코드
1-1) 클라이언트가 보낸 요청에 대한 처리 상태를 응답으로 알려주는 기능
- 1xx (Informational): 요청이 수신되어 처리중
- 실무에서 거의 사용하지 않음
- 2xx (Successful): 요청 정상 처리
- 200 : ok
- 201 : Created - 요청 성공해서 새로운 리스소가 생성됨
- 202 : Accepted - 요청이 접수되었으나 처리가 완료되지 않았음 / 잘 사용하지 않음
- 204 : No Content - 서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음
- 예) 웹 문서 편집기에서 save 버튼
- 3xx (Redirection): 요청을 완료하려면 추가 행동이 필요
- 300 : Multiple Choices (안쓴다)
- 301 : Move Permanently
- 302 : Found (현실적으로 기본값으로 사용)
- 303 : See Other (권장)
- 304 : Not Modified (캐시를 목적으로 사용)
- 307 : Temporary Redirect (권장)
- 308 : Permanent Redirect
- 300은 잘 사용하지 않음, 301~308은 사용함
- 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, 해당 위치로 자동 이동함 (리다이렉트)
- 동작 예시 :
- 요청 : 현재 폐기 예정인 API로 요청이 들어옴 -> /event
- 응답 : 301과 함께 새로운 API, Location: /new-event 전송
- 요청 : Get /new-event 로 재요청함
- 응답 : 200번 전달
- 리다이렉션 이해 :
- 영구 리다이렉션 : 특정 리소스의 URI가 영구적으로 이동
- 예) /members -> /users
- 예) /event -> /new-event
- 301 Moved PErmanently : 리다이렉트시 요청 메서드가 Get으로 변하고, 본문이 제거될 수 있음
- Post로 전송된 것을 Get으로 바꾸고 본문 제거
- 301 교환 예시
- 요청 : 메시지 포함 (POST, name=hello&age=20)
- 응답 : 301 Location: /new-event
- 요청 : GET /new-event 메시지는 삭제됨
- 응답 : 200
- 308 Permanent Redirect : 301과 기능은 같음, 리다이렉트시 요청 메서드와 본문 유지
- Post로 전송된 것을 Post로 보냄
- 308 교환 예시
- 요청 : 메시지 포함 (POST, name=hello&age=20)
- 응답 : 308 Location: /new-event
- 요청 : 메시지 유지 POST /new-event, name=hello&age=20
- 응답 : 200
- 일시 리다이렉션 : 일시적인 변경
- 주문완료 후 주문 내역 화면으로 이동
- PRG : Post/Redirect/Get
- 302 Found (실무에서 기본값으로 사용)
- 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
- 307 Temporary Redirect (권장)
- 302와 기능은 같음
- 리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안된다. Must Not)
- 303 See Other (권장)
- 302와 기능은 같음
- 리다이렉트시 요청 메서드가 GET으로 변경
- PRG: Post/Redirect/Get는 언제 사용할까?
* 기본적으로 거래와 같은 중요한 처리의 Post 전송은 주문번호 등을 할당함으로 중복 처리 방지
* 서버와 클라이언트 양쪽으로 예외처리가 진행되어야 함
* 개선된 처리 방법
1) 요청 : POST itemId=mouse&count=1
2) DB 저장 : 주문데이터 저장 (주문번호 할당)
3) 응답 : 302 Found Location:/order-result/19
4) 클라이언트 브라우저 자동 리다이렉트
5) 요청 : Get /order-result/19
6) 주문데이터 조회 / 예) 19번 주문
7) 응답 200
* 아마도, 장바구니에서 구매하기로 넘어갈때 예비 주문번호를 할당하는게 좋을듯 하다
* 2번 처리 중 응답 손실시, 중복 주문 발생 가능 사전에 배정된 주문번호 등으로 추적하여
현재 처리중인 주문이라는 메시지 등을 전송하거나 조회 화면으로 강제 이동
- 특수 리다이넥션
- 클라이언트 캐시가 만기되었을때 서버에 요청시, 그대로 사용하라고 명할 수 있음 등
- 결과 대신 캐시를 사용
- 304 Not Modified
- 캐시를 목적으로 사용
- 클라이언트에게 리소스가 수정되지 않았음을 알려준다. 따라서 클라이언트는 로컬 pc에 저장된
캐시를 재사용한다 (캐시로 리다이렉트)
- 304 응답은 응답에 메시지 바디를 포함하면 안된다. (로컬 캐시를 사용해야 함)
- 조건부 GET, HEAD 요청시 사용
* 실무에서는 301만 사용하고 Post로 와도 301로 처리하는경우가 대부분
- 4xx (Client Error): 클라이언트 오류, 장못된 문법등으로 서버가 요청을 수행할 수 없음
- 클라이언트의 요청에 잘못된 문법등으로 서버가 요청을 수행할 수 없음
- 오류의 원인이 클라이언트에 있음
- 중요! 클라이언트가 이미 잘못된 요청, 데이터를 보내고 있기 때문에, 똑같은 재시도가 실패함
- 클라이언트 개발자들과의 협업시 정확성을 위해 이러한 경우 에러를 명확히 보내줘야함
- 400 : Bad Request
- 클라이언트의 요청에 잘못된 문법등으로 서버가 요청을 수행할 수 없음
- 요청 구문, 메시지 등등 오류
- 클라이언트는 여청 내용을 다시 검토하고 보내야함
- 예) 요청 파라미터가 잘못되거나, API 스펙이 맞지 않을 때
- 오류의 원인이 클라이언트에 있음
- 401 : Unauthorized
- 클라이언트가 해당 리소스에 대한 인증이 필요함
- 인증 되지 않음
- 401 오류 발생시 응답에 WWW-Authentiucate 헤더와 함께 인증 방법을 설명
- 참고
- 인증(Authentcation) : 본인이 누구인지 확인, (로그인)
- 인가(Authorization) : 권한부여 (ADMIN 권한처럼 특정 리소스에 접근할 수 있는 권한, 인증이 있
어야 인가가 있음)
- 오류 메시지가 Unauthorized 이지만 인증 되지 않음 (이름이 아쉬움)
- 403 : Forbidden
- 서버가 요청을 이해했지만 승인을 거부함
- 주로 인증 자격 증명은 있지만, 접근 권한이 불충분한 경우
- 예) 어디믄 등급이 아닌 사용자가 로그인은 했지만, 어드민 등급의 리소스에 접근하는 경우
- 404 : Not Found
- 요청 리소스를 찾을 수 없음
- 요청 리소스가 서버에 없음
- 또는 클라이언트가 권한이 부족한 리소스에 접근할 때 해당 리소스를 숨기고 싶을 때
- 5xx (Server Error): 서버 오류, 서버가 정상 요청을 처리하지 못함
- 데이터베이스 등의 장애로 발생된 오류, 똑같은 요청을 하는 과정에서 성공할 가능성이 있음
- 서버 문제로 오류 발생
- 서버에 문제가 있기 때문에 재시도 하면 성공할 수도 있음(복구가 된 경우)
- 500 : Internal Server Error : 서버 문제로 오류 발생, 애매하면 500 오류
- 서버 내부 문제로 오류 발생
- 애매하면 500오류
- 503 : Service Unavailable : 서비스 이용 불가
- 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음
- Retry-After 헤더 필드로 얼마뒤에 복구되는지 보낼 수 있음
1-2) 만약 모르는 상태 코드가 나타나면?
- 클라이언트는 상위 상태코드로 해석해서 처리함
- 예) 299 ??? -> 2xx (Successful)
- 예) 451 ??? -> 4xx (Client Error)
- 예) 599??? -> 5xx (Server Error)
5. HTTP헤더 - 일반헤더
1) 콘텐츠 협상 (콘텐츠 네고시에이션) : 클라이언트가 선호하는 표현 요청
1-1) Accept : 클라이언트가 선호하는 미디어 타입 전달
1-2) Accept-Charset : 클라이언트가 선호하는 문자 인코딩
1-3) Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
1-4) Accept-Language: 클라이언트가 선호하는 자연 언어
* 협상 에더는 요청시에만 사용
2) 협상과 우선순위 : Quality Values(q)
- Quality Values(q) 값 사용
- 0~1, 클수록 높은 우선순위
- 생략하면 1
- Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=9.7
- ko-KR;q=1 (q생략)
- ko;q=0.9
- en-US;q=0.8
- en:q=0.7
- 구체적인 것이 우선한다
- Accept: text/*, text/plain, text/plain;format=flowed, */*
- text/plain;format=flowed
- text/plain
- text/*
- */*
- Accept도 우선권위를 할당할 수 있음
- Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,text/html;level=2;q=0.4, */*;q=0.5
3) 전송 방식
1-1) 단순 전송
- Content-Length : 컨텐츠의 길이 만큼 한번에 받는다
1-2) 압축 전송
- Content-Encoding : 압축 방식을 알려준다
1-1) 분할 전송
- Transfer-Encoding : chunked = 데이터 길이를 각각 별개로 선언하여 전송, 마지막 \r\n 전송
- Content-Length를 보내면 안된다
1-1) 범위 전송
- Range, Content-Range : 예) 다운받다가 정지된 파일은 새로 받을 위치부터 요청 가능
4) 일반 정보
- Referer : 이전 웹페이지 주소
- User-Agent : 내 웹 브라우저의 정보, 클라이언트 웹 브라우저 정보
- Server : 요청을 처리하는 Origin 서버의 소프트웨어 정보
5) 특별한 정보
- Host : 요청한 호스트 정보(도메인)
- 하나의 서버가 여러 도메인을 처리해야 할 때
- 하나의 IP 주소에 여러 도메인이 적용되어 있을 때
- Location : 페이지 리다이렉션
- Allow : 허용 가능한 HTTP 메서드
- Retry-After : 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
- Referer : 이전 웹페이지 주소
- Location : 페이지 리다이렉션
- 201 (Created) : Location 값은 요청에 의해 생성된 리소스 URI
- 3xx (Redirection) : Location 값은 요청을 자동으로 리디렉션하기 위한 대상 리소스를 가리킴
- Allow : 허용 가능한 HTTP메서드 (참고만 하자)
- 405 (Method Not Allowed)에서 응답에 포함해야 함
- Allow: GET, HEAD, PUT
6) 인증
- Authorization : 클라이언트 인증 정보를 서버에 전달
- WWW-Authenticate : 리소스 접근시 필요한 인증 방법 정의
6. HTTP헤더 - 캐시와 조건부 요청
1) 캐시 기본 동작
1-1) 캐시가 유효한 시간(초)를 헤더를 통해 전달함 (cache-control)
- 예) cache-control: max-age=60
2) 검증 헤더와 조건부 요청
1-1) 데이터가 마지막에 수정된 시간을 응답 메시지에 추가할 수 있음
- Last-Modified: 2020년 11월 10일 10:00:00
1-2) 해당 정보를 가지고 있는 Client의 캐시 시간 초과로 인한 요청 과정
- 요청 : if-modified-since: 2020년 11월 10일 10:00:00
- 응답 : 수정이 없는 경우, "304 Not Modified"를 HTTP BODY가 없이 전송함
1-3) ETag (Entity Tag)
- 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠
- 예) ETag: "v1.0",ETag: "a2jiodwjekjl3"
- 데이터가 벼녕되면 이 이름을 바꾸어서 변경함(Hash를 다시 생성)
- 예) ETag: "aaaaa" -> ETag: "bbbbb"
- 진짜 단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받음
1-4) 조건부 요청 헤더 정리
- If-Match, If-None-Match: ETag 값 사용
- If-Modified-Since, If-Unmodified-Since: Last-Modified 값 사용
3) 캐시와 조건부 요청 헤더
1-1) Cache-Control : 캐시 제어
- max-age : 캐시 유효 시간, 초 단위
- no-age : 데이터는 새시해도 되지만, 항상 원(Origin) 서버에 검증하고 사용
- no-store : 데이터에 민감함 정보가 있으므로 저장하면 안됨
메모리에서 사용하고 최대한 빨리 삭제
1-2) Pragma : 캐시 제어(하위 호환)
- HTTP 1.0 하위 호환 (지금은 거의 사용 안함)
1-3) Expires: 캐시 유효 기간(하위 호환)
- 캐시 만료 일자를 지정할 수 있음
- 지금은 더 유연한 Cache-Control: max-age 권장
4) 프록시 캐시
1-1) Cache-Control : 캐시 지시어(directives)
- Cache-Control: public
- 응답이 public 캐시에 저장되어도 됨
- Cache-Control: private
- 응답이 해당 사용자만을 위한 것임, private 캐시에 저장해야 함(기본값)
- Cache-Control: s-maxage
- 프록시 캐시에만 적용되는 max-age
- Age: 60 (HTTP 헤더)
- 오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)
5) 캐시 무효화
1-1) 확실한 캐시 무효화 응답
- Cache-Control: no-cache, no-store, must-revalidate
- Pragma: no-cache
- HTTP 1.0 하위 호환
1-2) Cache-Control: no-cache
- 데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용(이름에 주의!)
- 원 서버(Origin)가 순간 네트워크 단절로 접근이 불가할 경우,
캐시 서버 설정에 따라 오래된 데이터를 반환할 수 있음 (200 ok 응답)
1-3) Cache-Control: no-store
- 데이터에 민감함 정보가 있으므로 저장하면 안됨 (메모리에서 사용하고 최대한 빨리 삭제)
1-4) Cache-Control: must-revalidate
- 캐시 만료후 최초 조회시 원 서버에 검증해야함
- 원 서버 접근 실패시 반드시 오류가 발생해야함 - 504(Gateway Timeout)
- must-revalidate는 캐시 유효 시간이라면 캐시를 사용함
- 원 서버(Origin)가 순간 네트워크 단절로 접근이 불가할 경우,
항상 오류가 발생해야 함 - 504 Gateway Timeout (결제 등과 관련된 중요한 결과)
1-5) Pragma
- HTTP 1.0 하위 호환
7. 추가 정리
1) HTTP 깊이 학습 방법
- RFC 7230~7235 : https://tools.ietf.org/html/rfc7230
댓글