택배배달 생각해보기( 판매자 - 포장 - 택배로이동 - 도착 - 포장까기 - 구매자 )
Client - Server
- 리소스가 존재하는 공간과 리소스를 사용하는 앱을 분리시킨 것
- 리소스 사용 앱( Client ) / 리소스 존재 공간 ( Server )
일반적으로 서버는 리소스를 전달해 주는 역할만 한다.
리소스를 저장하는 공간을 별도로 마련해 두는데 이때 이 공간을 Database라고 한다 (DB) // 3-Tier Archietecture
클라이언트는 보통 플랫폼에 따라 구분됨 ( 웹사이트 (웹앱), 스마트폰/태블릿 앱, 데스크탑 앱)
서버는 어떤 작업을 하냐에 따라 종류가 달라짐 (파일서버, 메일서버, DB서버, 웹서버 등)
서버 통신과 API
- 클라이언트와 서버 간의 통신은 요청과 응답으로 구성됨. 요청이 있어야 응답이 온다.
- 클라 - 서버 간 통신은 프로토콜 (통신 규약)을 통해서 한다.
- Web Application Archietecture에서는 클라 - 서버 통신을 HTTP 프로토콜을 이용.
- 프로토콜 == 통신의 방법. 따라서 프로토콜(하는 방법) 은 여러 가지가 있을 수 있다.
- 각각의 프로토콜마다 지켜야 하는 규칙이 있다.
Types of Protocol
TCP/IP 4-layer-model
Transmission Control Protocol / Internet Protocol
현재 대다수의 응용 애플리케이션들이 인터넷과 통신하는 데 있어 TCP/IP 프로토콜을 사용한다. OSI 7-Layer model과 맵핑이 가능하다.
/ 로 묶여있지만 TCP와 IP는 엄연히 다른 개념이다. 네트워크의 경우, 위 모델처럼 계층이 정의되어있고, 각 레이어마다 하는 일과 책임 영역이 나뉘어 있기 때문에 하나로 묶어서 표현할 뿐이다.
모델에 계층이 나뉜 이유는 각 Layer에 대한 캡슐화와 정보의 은닉이 가능하기 때문이다.
Level 1 - [Network Interface Layer]
- OSI 모델의 Physical + Data Link layer에 해당 (Level 1, 2)
- 물리적 주소인 MAC을 사용
- LAN과 패킷망 등에 사용
Level 2 - [Internet Layer]
- OSI 모델의 Network Layer에 해당 (Level 3)
- 통신 노드 간 IP 패킷을 전송하는 기능과 라우팅 기능 담당
- 사용 프로토콜: IP, ARP, RARP
Level 3 - [Transport Layer]
- 통신 노드 간의 연결 제어
- 프로세스 간의 신뢰성 있는 데이터 전송
- 사용 프로토콜: TCP, UDP
Level 4 - [Application Layer]
- OSI 모델의 Session, Presentation, Application layer에 해당 (Level 5,6,7)
- 사용자와 가장 가까운 계층
- 동작을 위해 포트번호를 사용한다.
- 사용 프로토콜: HTTP, SSH, FTP, Telnet, SMTP 등
API
Application Programming Interface
서버는 클라이언트에게 리소스를 잘 활용할 수 있도록 인터페이스를 제공해야 한다. 이때 이 인터페이스가 API이다.
예를 들어, 타이 레스토랑에 갔다고 가정해보자. 메뉴판을 보면 해당 레스토랑에서 판매하는 타이 음식들을 확인할 수 있는데 이는 또한 엉뚱한 메뉴 (타이 레스토랑에서 갑자기 비빔밥을 찾는다던가)를 고르지 않도록 손님들을 도와주는 역할도 한다. 즉, "메뉴에 있는 음식만 주문 가능하다"라고 음식점이 메뉴판을 설계했고, 손님들은 거기에 맞춰 적절한 주문 (요청)을 할 수 있다. 여기서 메뉴판을 API라고 볼 수 있다.
예시로 확인했듯이, 서버 측에서 리소스 전달을 위한 메뉴판 (API)를 구축해놔야 클라이언트에서 활용할 수 있다.
보통 인터넷 상의 데이터를 요청할 때는 HTTP를 사용하고 주소 (URL, URI)를 통해 접근할 수 있다.
HTTP API 메서드
HTTP 요청 시, 자바처럼 메서드를 이용하여 리소스와 관련된 행동( CRUD: create / reade / update / delete ) 들을 지정할 수 있다.
요청 | 메서드 |
조회 (Read) | GET |
추가 (Create) | POST |
갱신 (Update) | PUT / PATCH |
삭제 (Delete) | DELETE |
HTTP 요청 메서드 - HTTP | MDN
HTTP는 요청 메서드를 정의하여, 주어진 리소스에 수행하길 원하는 행동을 나타냅니다. 간혹 요청 메서드를 "HTTP 동사"라고 부르기도 합니다. 각각의 메서드는 서로 다른 의미를 구현하지만, 일부
developer.mozilla.org
URL / URI
URL (Uniform Resource Locator)는 네트워크 상에서 웹 페이지, 이미지, 동영상 등의 파일 위치정보를 나타낸다. URL은 크게 [ scheme, host, url-path ]의 3 부분으로 구분한다.
URI (Uniform Resource Identifier)는 URL의 기본 3 요소인 [ scheme, host, url-path ]에 추가로, query와 bookmark를 포함한다. https://www.google.com:80/search?q=Java
브라우저의 검색창을 클릭했을 때 나타나는 주소가 URI이다. URI는 URL을 포함하는 상위 개념이다.
즉, URL은 URI이고 / URI는 URL이 아니다.
부분 | 명칭 | 설명 |
file://, http://, https:// | scheme | 통신 프로토콜 |
127.0.0.1, www.naver.com | hosts | 웹 페이지, 이미지, 동영상 등의 파일이 위치한 웹 서버, 도메인 또는 IP |
:80, :443, :3000 | port | 웹 서버에 접속하기 위한 통로 |
/search, /Users/username/Desktop | url-path | 웹 서버의 root 디렉토리로부터, 웹 페이미, 이미지, 동영상 등의 파일의 위치까지의 경로 |
q=Java | query | 웹 서버에 전달하는 추가 질문 |
IP와 포트
네트워크에 연결된 특정 PC의 주소를 나타내는 체계를 IP address(Internet Protocol address, IP주소) 라 한다.
그리고 IP 주소에 진입할 수 있게 해주는 통로를 PORT(포트)라고 한다.
127.0.0.1처럼 (. )을 기준으로 4덩어리의 숫자로 구성된 IP 주소 체계를 IPv4라고 하며 (Internet Protocol version 4) IPv4는 각 덩어리마다 0~255 사이의 숫자로 나타낼 수 있고 총 2^32 (약 43억) 개의 IP주소를 표현할 수 있다.
다음의 주소는 이미 용도가 정해져 있어서 반드시 기억해야 한다.
- localhost, 127.0.0.1 :
현재 사용 중인 로컬 PC를 지칭함 - 0.0.0.0, 255.255.255.255 :
로컬 네트워크에 접속된 모든 장치와 소통하는 주소 (broadcast address) 서버에서 접근 가능한 주소를 broadcast address로 지정하면, 모든 기기에서 서버에 접근 가능하다.
시간이 흐르면서 IPv6도 나오게 되었는데 IPv4와는 다른 표기법을 가지고 있어 총 2^128개의 IP주소를 표현할 수 있다.
FE80:CD00:0000:0 CDE:1257:0000:211 E:729C
PORT
- 포트( 통로 )를 통해 IP 주소로 접근할 수 있다.
- 이미 사용 중인 포트는 중복 사용이 불가능하다.
포트를 왜 쓰는지 이해하기 위해서는 데이터가 컴퓨터 간 네트워크를 통해 어떻게 이해하는지 큰 그림으로 먼저 이해할 필요가 있다.
서버 프로그램이 처음 실행되면, 지정된 포트번호에 할당된다. 그리고 이 서버를 사용하는 모든 클라이언트 프로그램들은 지정된 포트번호에 할당되어야 한다.
발신지 컴퓨터에서 출발한 패킷이 TCP/IP의 계층을 거쳐서 최종적인 목적지 IP를 가지고 있는 컴퓨터에 전송이 된다. 이때, 도착지 컴퓨터에서 실행 중인 많은 프로그램들 중 누구에게 데이터를 전달해야 하는지 확실한 지표가 필요한데 이때, 프로그램의 논리적 주소인 Port 번호를 이용한다.
즉, 각각의 응용 프로그램에 Port 번호를 할당해서 데이터가 전송계층에서 어느 프로그램으로 갈지 구분하게 한다.
포트 번호는 0부터 65,535까지 사용할 수 있다. 그중에서 0부터 1024까지의 포트 번호는 주요 통신을 위한 규칙에 따라 이미 정해져 있는데 꼭 알아야 할 잘 알려진 포트번호는 아래와 같다.
- 22 : SSH
- 80 : HTTP
- 443 : HTTPS
List of TCP and UDP port numbers - Wikipedia
en.wikipedia.org
이미 정해진 포트 번호라도, 필요에 따라서 자유롭게 사용이 가능하다. 위처럼 잘 알려진 포트 번호의 경우, URI에서 표시하지 않지만, 잘 알려지지 않는 포트 (예 :8080 같은 임시 포트)를 사용할 경우에는 반드시 URI에 포함해야 한다.
Domain name
웹 브라우저를 통해 특정 사이트에 방문할 때, IP 주소를 대신해서 Domain name을 사용해서 접속할 수도 있다.
IP주소가 주소의 지번, 도로명 주소라면 / 도메인 이름은 해당 주소에 위치한 상호명이라고 볼 수 있다.
위 사진에서 google.com 이 Domain Name이고, 172.217.161.46이 IPv4형식의 IP 주소이다. 즉, 주소창에 IP주소를 치던, 도메인 이름을 치던, google.com으로 이동하게 된다.
DNS
DNS (Domain Name System)은 호스트의 Domain Name을 IP주소로 변환하거나, 그 반대의 경우를 수행할 수 있도록 개발된 DB 시스템이다.
네트워크 상의 모든 PC들은 IP주소를 갖고 있지만, 그렇다고 모든 PC가 Domain Name을 가지고 있는 것은 아니다. 로컬 PC를 나타내는 127.0.0.1은 localhost로 사용 가능하지만, 그 외에는 따로 Domain name을 대여해서 사용한다.
예를 들면 지금 내 블로그 주소를 danc.com으로 바꾸고 싶다면, 따로 도메인을 구입해서 일정기간 대여를 하는 식이다.
이렇게 도메인을 대여하고 난 뒤, 도메인 이름으로 특정 사이트로 이동하기 위해선 다음의 과정을 거친다.
- 해당 Domain Name과 매칭 된 IP주소를 찾는다 ( 네트워크에 이것을 위한 서버가 별도로 존재한다)
- 매칭 된 IP주소에 해당하는 웹 서버로 요청을 넣고, 클라이언트와 서버가 통신하게 만들어 준다.
AJAX
SPA (Single Page Application)를 만드는 기술인 AJAX에 대해 알아보자.
AJAX (Asynchronous JavaScript And XMLHttpRequest)는 JS, DOM, Fetch, XMLHttpRequest, HTML 등의 다양한 기술을 활용하는 웹 개발 기법으로써, 웹 페이지에 필요한 부분에 필요한 데이터만 비 동기적으로 따와서 화면에 출력할 수 있다.
구글 검색 페이지에 접속하게 되면, 웹 페이지의 html에 의해서 유저에게 필요한 페이지가 렌더링 된다. 하지만 딱 한 부분은 html에 작성된 대로 유저가 사용하는 것이 아니라, 유저의 요구에 따라 반응하며 변화하는 부분이 있는데 바로 검색창 부분이다.
검색창에 글자를 입력할 때마다 해당 글자의 추천 검색어를 서버에서 받아와 표시해주게 되는데, 이 과정이 필요한 데이터만 비 동기적으로 받아와 렌더링을 하게 되는 것이다. 바로 이때 AJAX가 사용된다.
구글 말고도 스크롤을 내릴 때마다 계속 다음 목록이 갱신되는 웹 페이지들도 볼 수 있는데 이를 무한 스크롤이라 한다. 무한 스크롤이 발생될 때마다 Fetch를 통해 데이터를 따와서 업데이트하고 렌더링 한다. 이때도 AJAX가 사용된다.
AJAX 핵심 기술
AJAX를 구성하는 핵심 기술은 JS와 DOM, 그리고 Fetch이다.
예전에는 <form> 태그를 이용해서 서버에 데이터를 전송하고, 서버는 응답으로 새로운 웹 페이지를 제공했다. 즉 클라이언트 쪽에서 요청을 하면 매번 새 페이지로 이동해야 하는 번거로움이 있었다.
하지만 Fetch를 사용하면, 서버에서 바로 필요한 데이터를 받아올 수 있어 더 이상 새 페이지로 이동할 필요가 없다. Fetch는 User가 현재 웹 페이지에서 작업을 하는 동안 서버와 통신할 수 있게 도와준다.
즉 Fetch가 서버와 통신할 때 브라우저가 멈추는 것이 아니라, 계속해서 페이지를 사용할 수 있게 하는 비동기적인 방식을 사용한다. 또한 JS에서 DOM을 활용할 수 있기 때문에 Fetch를 통해서 전체 페이지를 가져오는 것이 아닌, 그때그때 필요한 데이터만 가져와서 DOM에 적용시켜서 현재 페이지에서 필요 부분만 변경할 수 있다.
XHR과 Fetch
Fetch가 나오기 전에는 XHR (XMLHttpRequest)를 사용했다.
Fetch는 XHR의 단점을 보완한 새로운 웹 API이며, 상대적으로 가볍고 JSON을 사용하기 때문에 JS와도 호환이 가능하다. 또한 간편하고 promise 지원 등의 장점이 많기 때문에 Cross-Site 이슈 등의 불편함이 있던 XHR 대신 현재는 Fetch를 많이 사용한다.
AJAX 장점
- 서버에서 HTML을 완성해서 보내지 않아도 웹 페이지를 만들 수 있다.
- 예전에는 완성된 HTML을 서버에 보내야 화면에 렌더링 할 수 있었지만, AJAX를 사용하면 필요한 데이터를 비동기적으로 가져와 브라우저 화면의 일부만 업데이트해서 렌더링 할 수 있다.
- 예전에는 완성된 HTML을 서버에 보내야 화면에 렌더링 할 수 있었지만, AJAX를 사용하면 필요한 데이터를 비동기적으로 가져와 브라우저 화면의 일부만 업데이트해서 렌더링 할 수 있다.
- XHR이 표준화되면서 브라우저에 상관없이 AJAX를 사용할 수 있다.
- 이전에는 브라우저마다 다른 방식으로 AJAX를 사용했어야 했다.
- 이전에는 브라우저마다 다른 방식으로 AJAX를 사용했어야 했다.
- 유저 중심 application 개발 AJAX를 사용하면 빠르고 더 많은 상호작용 가능한 application을 만들 수 있다.
- 더 작은 대역폭
- 이전에는 완성된 HTML을 서버에서 받아와야 해서 한 번에 보내는 데이터의 크기가 컸다.
- AJAX는 필요한 데이터를 text형태 (JSON, XML)등으로 보내면 되기 때문에 데이터의 크기가 비교적 작다.
AJAX 단점
- 뒤로 가기 버튼 문제
- AJAX에서는 이전 상태를 저장하지 않기 때문에, 따로 History API 기능을 구현해서 사용해야 한다.
- SEO (Search Engine Optimization) 측면에서의 불리함
- AJAX는 한번 받은 HTML을 먼저 렌더링 -> 서버에서 비동기적으로 필요한 데이터를 가져와 렌더링 하기 때문에
HTML 파일에 데이터를 채우기 위한 틀만 작성된 경우가 많다. - 따라서 사이트의 정보를 긁어오기 (크롤링) 어렵다.
- AJAX는 한번 받은 HTML을 먼저 렌더링 -> 서버에서 비동기적으로 필요한 데이터를 가져와 렌더링 하기 때문에
- 반드시 JS를 써야 한다.
- 레이아웃이 복잡한 웹 페이지는 렌더링 할 때 속도 저하가 발생할 수 있다.
SSR & CSR
SSR
SSR (Server Side Rendering)은 웹 페이지를 브라우저에서 렌더링 하는 대신, 서버에서 렌더링 한다.
브라우저가 서버의 URI로 GET 요청을 보내면, 서버는 요청받은 웹 페이지 파일을 브라우저로 전송하고, 파일이 브라우저에 도착하게 되면 완전히 렌더링 된다.
만약 웹 페이지의 내용에 DB 데이터가 필요할 경우에는, 서버가 DB의 데이터를 불러온 다음, 완전히 렌더링을 하고 브라우저로 '응답'으로써 보낸다.
사용자가 다른 페이지로 이동하게 되면 서버는 다시 해당 작업을 수행한다.
CSR
CSR (Client Side Rendering)은 일반적으로 SSR의 반대라고 생각하면 된다.
CSR은 클라이언트에서 페이지를 렌더링 하게 되고, 대표적은 클라이언트는 지금 쓰는 웹 브라우저다.
브라우저가 요청을 보내면 서버는 웹 페이지의 프레임이 될 단일 페이지를 JS 파일과 함께 브라우저로 보낸다. 브라우저가 해당 파일들을 받으면 브라우저에서 렌더링 최종적으로 하게 된다.
필요한 데이터가 DB에 저장되어 있는 경우에는 브라우저가 API 요청으로 해결하게 된다.
사용자가 다른 페이지로 이동해도 서버가 웹 페이지를 다시 보내지 않는다. 다만 브라우저에서 브라우저가 요청한 경로에 따라서 페이지를 다시 렌더링 한다. 이때 보이는 웹 페이지의 파일은 처음 서버로부터 받은 파일과 같다.
SSR vs CSR
CORS
CORS (교차 출처 리소스 공유 / Cross-Origin Resource Sharing)는 추가적인 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다.
웹 애플리케이션은 리소스가 자신의 출처(Domain / Protocol / Port)와 다를 때 교차 출처 HTTP 요청을 실행한다.
브라우저에서는 보안을 이유로 cross-origin, 즉 다른 도메인의 리소스를 가져오는 것이 불가능한데 (SOP - Single Origin Policy) 이를 해결하기 위해서 CORS를 사용하게 된다.
Preflighted Request
Cross-Origin 요청은 유저 데이터에 영향을 줄 수 있기 때문에, 먼저 OPTIONS 메서드를 통해서 '혹시 다른 도메인에 있는 리소스로 HTTP 요청을 해도 안전할까요???' 하고 물어본 뒤에 안전한 경우, 실제 요청을 보낸다.
// *Preflight Request / Response
OPTIONS /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Access-Control-Request-Method: POST // Access-Control-Request-Headers: X-PINGOTHER, Content-Type
위의 2개의 헤더는 실제로 요청을 할 때 POST메서드로 전송하겠다는 것을, 그리고 X-PINGOTHER와 Content-Type 사용자 정의 헤더와 함께 전송된다는 것을 서버에 알린다.
이를 토대로 서버 측에서 이런 상황에서 요청을 수락할지 말지 결정한다. (Access-Control-Allow-xxxx)에서 Allow가 있으니 사용이 허가됐다는 것을 알 수 있다.
// *Real Request / Response
POST /doc HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: https://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: https://foo.example
Pragma: no-cache
Cache-Control: no-cache
<person><name>Arun</name></person>
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain
[Some XML payload]
'web > NETWORK' 카테고리의 다른 글
HTTP (0) | 2022.08.10 |
---|---|
HTTPS 인증/보안 기초 정리 (0) | 2022.07.21 |