웹 동작방식 이해하기
웹의 동작방식
IP 주소란?
image from PIXABAY
거대한 네트워크망에서 여러분의 컴퓨터를 식별하기 위한 위치 주소 입니다.
지금은 실제로 네트워크라는 공간에서 여러분 컴퓨터의 집주소라고 비유적으로 생각하셔도 좋습니다.
네트워크상에서의 데이터 송/수신은 이 주소를 기준으로 이루어지고 있습니다.
👌 192.168.0.123 와 같이 생긴 숫자가 IP주소라고 불리는 것을 본 적 있으시죠?
브라우저란?
image from PIXABAY
지금 여러분이 사용하고 계시는 크롬, 사파리, 엣지와 같이
웹페이지, 이미지, 비디오등의 컨텐츠를 송/수신하고 표현해주는 소프트웨어입니다.
👌 브라우저가 해주는 일 중 그래도 가장 큰 일 두가지를 명심하면 좋을 것 같습니다 ”컨텐츠를 송/수신한다”, “컨텐츠를 표현한다” 그리고 지금은 “컨텐츠를 송/수신한다”에 초점을 더 맞춰볼까 합니다.
지금 모두 이야기 할 수 없지만, 컴퓨터, 전기신호등은 0과 1밖에 표현하지 못합니다. 데이터의 송/수신 역시 0과 1의 아날로그 신호로 이루어지는데, 여러분의 브라우저는 여러분의 메세지가 OSI 7 계층을 거쳐 랜선을 통해 0과 1로 변경되어 흘러갈 수 있도록 여러분을 도와주는 응용프로그램이자, 여러분과 상호작용해서 요청을 보내는 응용프로그래밍 계층의 첫 출발점입니다.
DNS(Domain Name Server)란?
image from PIXABAY
개발자가 아닌 일반적인 삶을 살 때 IP주소와 같은 것들을 접할 기회는 거의 없습니다. 우리가 실제로 웹 브라우저를 열고 웹 사이트로 이동할 때는 긴 숫자를 기억해 입력한적은 없죠. 그 대신 abcdefg.com과 같은 도메인 이름 을 입력해서 원하는 웹 사이트로 이동해왔습니다.
어떻게 이런일이 가능했을까요?
바로 중간에 여러분의 요청을 받아줄 서버의 IP주소(192.168.0.123)와 여러분이 외우고 있는 도메인 이름을 중개해주는 전화번호부와 같은 서버가 중간에 있었기 때문입니다.
IP 주소 Domain 이름
192.168.0.123 | www.hello.com |
192.168.0.124 | www.world.com |
실제로도 위와 같은 모습으로 되어 있는 중개 서버가 있기에, 여러분은 도메인 이름(사이트 주소)만 외워도 목적지를 알 수 있어 요청을 보낼 수 있게 됩니다.
서버로 요청을 보낸다면?
🤔 요청을 받을 주소(IP주소)도 알았고, 요청을 보낸 주소도 알았고(DNS를 통해서), 요청을 송/수신해주는 도구도 있는데 그러면 요청을 보낼 수 있겠네요?
네이버의 도메인이 www.naver.com 이라는건 알고 있고, DNS를 통해 받아온 주소가 (192.0.0.0)이라고 생각하고, 내 IP주소가 (192.0.0.1)이라고 생각하고 요청을 보내볼까요?
🙂 to. 192.0.0.0 안녕하세요! 저는 192.0.0.1 라는 IP를 가지고 있는 사람인데요! 저에게 네이버의 첫 페이지의 html/css/js를 조금 주실 수 있나 해서요! 제 IP 주소로 보내주시면 될 것 같아요.
🙃 (네이버의 서버 개발자) : ….
서버개발자 입장에서 저 요청을 어떻게 받아들여야 할까요?
서버 프로그램도 결국 컴퓨터고, 사람이나 ai가 아닌 컴퓨터 프로그램입니다.
여러분이 프로그래밍을 한다면 어떻게 해야 할까요?
사실 저렇게 메세지를 보낸다면, 결국 저 요청의 텍스트를 “\n”으로 자르고,
정규식으로 데이터를 각각 받아서 잘라줘야 할 겁니다.
만약 어떻게든 요청을 처리했는데, 다른 사람은 또 다르게 보내면 어쩌죠?
사람마다 코드를 다시 짜야 할까요?
여기서 여러분들이 잘 알고있는 메세지 송신자와 수신자가 공유하고 있는 “약속”의 개념이 등장합니다.
HTTP란 ??
image from PIXABAY
다시 돌아와서 요청을 보내고 받는 상호간에 “**약속”**을 하고 있다면 어떨까요?
예를 들어 요청을 보내는 사람은
첫줄에 주소를 적고,
두 번째 줄에 자신의 IP주소를 적고,
세 번째 줄에 보내고자 하는 정보를 적고,
각각의 정보를 “ : “ 로 구분해서 적겠다고 약속하고,
상호간에 “**그 약속을 공유”**하고 있다면 어떨까요?
🤔 Request URL : www.naver.com Address : 192.0.0.1 … Request Body : “네이버 첫 페이지 데이터좀 주세요!”
모든 요청이 이처럼 약속된 방식으로 들어오고 모든 응답도 양식을 정해뒀다면, 그 요청을 일괄로 처리 할 수 있게 됩니다. 멀리 떨어져서 서로에 대한 정보가 없는 메세지의 송/수신자가 서로 필요한 요청과 응답을 할 수 있도록 미리 규약을 정해놓은 것을 **“프로토콜”**이라고 하고, 웹 상에서는 HTTP 라는 프로토콜을 통해서 데이터를 송/수신 하고 있습니다.
여러분이 서버개발자가 되고자 한다면, 혹은 프론트엔드 개발자로 직군을 변경한다고 해도, 웹 프로그래밍을 하려면 HTTP라는 프로토콜을 정확하게 이해하고 있어야, 정확하게 요청을 받고, 요청을 처리한 결과를 응답 할 수 있습니다. 다만 너무 걱정할 필요 없는 것은, HTTP 프로토콜이 웹 프로토콜중 가장 많이 사용 되는 이유는 상대적으로 간단하고 쉽기 때문이기에 여러분들이 적당한 시간만 투자한다면, 주요한 내용을 습득하는데 어려움이 있지 않을거에요. 물론 더 자세한 내용은 조금 더 뒤에 다루도록 하고, 지금은 이러한 통신 규약이 있어서 클라이언트와 서버간에 메세지를 주고받을 수 있다고 생각해주시면 좋을 것 같습니다.
🙂 더 자세한 http 관련 내용이 궁금하시다면, 아래 보너스 자료를 이용해주세요!
드디어 요청이 서버에 도달했습니다!
잘 따라오셨다면, 지금까지 한 이야기가 “우리가 지금까지 이야기 한 내용!!” 이라고 적힌 부분에 대한 이야기라는 것을 이해하실 수 있으실 겁니다. 결과적으로 클라이언트(지금까지 웹서핑을 해오던 우리)의 요청은 서버에 도달했고, “**API”**라는 서버의 창구와 같은 곳에 도달합니다. 그리고 당연하게도 지금부터 이야기들은 전부 우리가 “서버 개발자”로서 실제로 코딩을 해야하는 부분과 관련된 이야기 입니다.
API(application programming interface)는 다른 소프트웨어 시스템과 통신하기 위해 따라야 하는 규칙을 정의합니다. 개발자는 다른 애플리케이션이 프로그래밍 방식으로 애플리케이션과 통신할 수 있도록 API를 표시하거나 생성합니다. 예를 들어, 근무 시간 기록 애플리케이션은 직원의 전체 이름과 날짜 범위를 요청하는 API를 표시합니다. 이 정보가 수신되면 내부적으로 직원의 근무 시간 기록을 처리하고 해당 날짜 범위에서 근무한 시간을 반환합니다.
웹 API는 클라이언트와 웹 리소스 사이의 게이트웨이라고 생각할 수 있습니다.
인터페이스(interface)는 서로 다른 두 개의 시스템, 장치 사이에서 정보나 신호를 주고받는 경우의 접점이나 경계면이다. 즉, 사용자가 기기를 쉽게 동작시키는데 도움을 주는 시스템을 의미한다. 컴퓨팅에서 컴퓨팅 시스템끼리 정보를 교환하는 공유 경계이다. 이러한 교환은 소프트웨어, 컴퓨터 하드웨어, 주변기기, 사람간에 이루어질 수 있으며, 서로 복합적으로 이루어질 수도 있다.
아직 설명이 와닿지 않는다면, 하나의 "약속" 이자, 서로 다른 어플리케이션 간에 약속한 방식으로 요청을 하면 정해진 결과물, 즉 요청을 받아 응답을 돌려주는 식당의 점원이라고 비유적으로 이해하셔도 좋을 것 같습니다.
이 부분은 우리 모두가 들었던 웹개발 플러스 강의 내용을 떠올려보면 좋을 것 같습니다.
from flask import Flask
def create_app():
app = Flask(__name__)
@app.route('/PrintHelloWorld')
def hello_world():
return 'Hello, World!'
@app.route('/HelloWorldTemplate')
def hello_world():
return render_template('HelloWorldTemaplate")
return app
우리의 서버 역할을 해주던 플라스크에 있었던 위와 같은 코드가 기억나시죠? 도메인 이름 뒤에 오는 양식을 맞춰주기만 하면 플라스크가 알아서 해당 함수를 호출해줬던 것을 기억하실겁니다.
🙂 만약 우리의 도메인이 (www.serverDeveloper.com)이고, 도메인 뒤에 @app.route()안에 들어간 정보들을 써주면, 해당 어노테이션이 붙어있는 함수가 호출되었습니다.
www.serverDeveloper.com/HelloWorldTemplate ⇒ HelloWorldTemplate이라는 html/css/javascript 로 구성된 template이 클라이언트로 전송되어 브라우저가 그려주게됩니다. 아마도 해당 template에는 그 “웹페이지”안에서 다른 요청을 보낼 수 있는 ajax와 같은 코드들도 포함되어 있어 연속적으로 웹페이지를 이용 할 수 있게 하겠죠?
즉 @app.route()와 같은 표시가 붙은 함수들이 사용자들의 요청을 가장 먼저 맞이해주는 역할을 해줬고, 이러한 역할과 명세를 잘 정리해두면 api 명세가 되고, 우리 서버 프로그램의 식당 점원의 역할을 해줬던 겁니다.
🤔 그러면 서버는 요청을 받아 html/css/js 파일을 반환해주는게 주 업무인가요?
☝ 당연히 정답은 없지만, 최근의 경향으로는 그렇지는 않습니다. 예전에는 조금 더 그랬었던 편이지만, 웹 생태계가 고도화 되는 과정중에 상대적으로 프론트엔드와 백엔드가 각각 따로 발전하게 되면서, 느슨하게 결합하는 방식을 더 많이 채택하게 되었고, 최근에는 서버가 직접 뷰(html/css/js)를 반환하기 보다는 요청에 맞는 특정한 정보만 반환하는 것을 조금 더 선호하기도 합니다. 그래서 요즘에는 주로 서버는 JSON이라는 형태로 데이터만 반환하기도 하는데, 보통 이렇게 생겼습니다!
RESTful API란?
REST란 무엇인가요?
Representational State Transfer(REST)는 API 작동 방식에 대한 조건을 부과하는 소프트웨어 아키텍처입니다. REST는 처음에 인터넷과 같은 복잡한 네트워크에서 통신을 관리하기 위한 지침으로 만들어졌습니다. REST 기반 아키텍처를 사용하여 대규모의 고성능 통신을 안정적으로 지원할 수 있습니다. 쉽게 구현하고 수정할 수 있어 모든 API 시스템을 파악하고 여러 플랫폼에서 사용할 수 있습니다.
API 개발자는 여러 아키텍처를 사용하여 API를 설계할 수 있습니다. REST 아키텍처 스타일을 따르는 API를 REST API라고 합니다. REST 아키텍처를 구현하는 웹 서비스를 RESTful 웹 서비스라고 합니다. RESTful API라는 용어는 일반적으로 RESTful 웹 API를 나타냅니다. 하지만 REST API와 RESTful API라는 용어는 같은 의미로 사용할 수 있습니다.
RESTful API란 무엇인가? - RESTful API 초보자 가이드 - AWS
걱정마세요 지금은 이해가 어려워도 나중에 http를 더 알게되면 알 수 있습니다.
조금 일반적으로 쉬운 말로 바꾸면, 여러분 서버의 api가 적절하게 http를 준수하며 잘 설계되어있으면 RESTful 하게 설계되어 있다고 당분간은 이해하셔도 좋을 것 같습니다.
예를들어 여러분이 api의 리소스 식별자를 ex - (”/”) 중복 없이 고유하게 잘 만들고,
해당 api에 적절하게 http메서드를 사용했다면, RESTful하게 설계했다고 볼 수 있겠죠?
🤔 지금은 여러분 서버의 api가 HTTP 프로토콜을 잘 준수하면 저렇게 멋있는 형용사가 붙는다는 정도로만 기억하면 좋을 것 같습니다! RESTful!
서버가 요청을 처리하기 위한 자료들?
우리가 서버로 특정한 요청을 처리하는데, 필요한 것이 하나 더 있습니다.
그리고 그 부분을 지금 이야기 해 보려고 합니다.
마찬가지로 우리가 웹개발 플러스 강의를 들으며 진행했던 로그인 로직을 생각해보면 좋을 것 같습니다.
@app.route('/sign_in', methods=['POST'])
def sign_in():
username_receive = request.form['username_give']
password_receive = request.form['password_give']
pw_hash = hashlib.sha256(password_receive.encode('utf-8')).hexdigest()
# 여기!!!!
result = db.users.find_one({'username': username_receive, 'password': pw_hash})
if result is not None:
payload = {
'id': username_receive,
'exp': datetime.utcnow() + timedelta(seconds=60 * 60 * 24) # 로그인 24시간 유지
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
return jsonify({'result': 'success', 'token': token})
else:
return jsonify({'result': 'fail', 'msg': '아이디/비밀번호가 일치하지 않습니다.'})
클라이언트의 요청이 네트워크를 타고 들어와서, “새로운 정보”인 유저의 ID/Password를 들고 들어왔습니다.
@app.route('/sign_in', methods=['POST'])
이제는 위와같은 어노테이션을 통해 sign_in 메서드가 요청을 처리하기 위해 점원의 역할을 한다는 것도 알게 되었죠
하지만 우리에게는 한 가지 정보가 더 필요합니다. 바로 “기존의 정보” 입니다.
기존의 정보가 있어야 유저가 로그인을 시도하려는 아이디 비밀번호와 같이 대조 해 볼 수 있겠죠?
그리고 그러한 정보는 이미 생성되어 가지고 있거나, 서버의 동작을 통해서(예를들어 회원가입과 같은) 저장되어 활용이 가능해야 합니다.
보통의 서버는 위와 같은 필요성 때문에, 데이터를 저장하고 관리하는 데이터베이스를 두게 됩니다.
“여기 !!!!” 라고 주석처리된 부분의 코드를 보시면 알 수 있듯 우리는 웹개발 플러스 프로젝트에서 몽고디비라는 데이터 베이스를 이용했었죠.
하지만 일반적으로 몽고디비와 같은 데이터베이스는 빅데이터 등 특정 도메인에서 매우 유용하지만, 우리가 앞으로 처리할 다양한 상황에서 아쉬운 점이 있습니다. 그래서 우리는 곧 산업군에서 가장 많이 사용되고 있는 관계형 데이터 베이스에 대해서도 알아볼 예정입니다.
🤔 데이터베이스는 왜 있으며, 왜 다양한 종류가 있나요?
👉 처음 접하는 분들이 가장 쉽게 오해하기로는, “정해진 공간에 최대한 많은 데이터를 저장하기 위해서” 일 겁니다. 하지만 사실 데이터베이스는 데이터를 “효율적으로 성능 좋게” 다루기 위해 존재합니다.
즉 더 많이 저장하기 위해서가 아니라, 저장 조회 수정 삭제등을 더 빠르고 효율적으로 처리하기 위해서, “성능상의 이점”을 얻기 위해서 사용한다고 생각하면 좋을 것 같습니다.
이러한 맥락에서 데이터를 사용,활용하는 주체에 따라서 더 효율적인 방법이 각각 다르다 보니 다양한 형식의 데이터베이스가 존재하게 됩니다.
결론
👉결론적으로 서버 개발에서 그래도 가장 많이 하는 일은, “새로운 정보”와 “기존의 정보”를 가지고 “정해진 로직”을 수행하는 일 입니다. 위와같은 이야기를 하기 위해서, 0. 기존에 알고있던 웹 프로그램이 어떻게 동작하는지를 살펴봤고 1. 어떻게 새로운 정보인 클라이언트의 요청이 서버로 도달하는지를 살펴봤고 2. 어떻게 기존의 정보를 저장하는지를 살펴봤습니다. 다음시간에는 이 세가지 맥락을 그대로 가져가면서 드디어 우리의 주특기인 스프링 부트를 설명해보려 합니다!
'개발 > Spring' 카테고리의 다른 글
spring 서버 연결 메모만들기 (0) | 2023.02.04 |
---|---|
mvc (0) | 2023.02.04 |
JPA 연습! (0) | 2023.02.04 |
SQL 설정 및 연습! (0) | 2023.02.03 |
SpringBoot 및 서버 이해 (0) | 2023.02.03 |