웹 서버 심화
학습 목표
-
Flask 기반 웹 서버를 MTV 패턴으로 구성하고 역할을 이해
-
환경 설정(
config.py)과 앱 초기화(server/__init__.py) 흐름 파악 -
SQLAlchemy 모델 정의와 폼 제출 → DB 저장 라우트 구현 연습
-
Jinja 템플릿으로 입력 폼을 작성하고 렌더링하는 방법 학습
-
run_server.py로 애플리케이션을 실행해 동작을 확인
MTV 패턴
MTV 패턴은 웹 애플리케이션을 구조적으로 나누어 개발하기 위한 아키텍처 패턴으로,
Model, Template, View 세 가지 역할로 구성된다.
일반적인 MVC(Model–View–Controller) 패턴과 유사하지만, 웹 프레임워크(특히 Django)에서는 MTV라는 용어를 자주 사용한다.
구성 요소
Model (모델)
-
데이터와 관련된 모든 것을 담당한다.
-
데이터베이스 테이블 구조를 정의한다.
-
레코드를 생성, 조회, 수정, 삭제(CRUD)하는 로직을 포함한다.
-
예:
-
User,Post,Product등 도메인 객체 -
Django의
models.py, Flask + SQLAlchemy의 모델 클래스
-
Template (템플릿)
-
사용자에게 보여지는 화면(View, UI)을 담당한다.
-
HTML 기반의 템플릿 파일로, 동적으로 데이터를 표시한다.
-
템플릿 엔진(예: Jinja2, Django Template Language)을 사용하여 변수 출력, 반복, 조건문 등을 처리한다.
-
예:
-
templates/index.html -
templates/user_detail.html
-
View (뷰)
-
사용자의 요청(Request)을 받고, 응답(Response)을 생성하는 역할을 한다.
-
비즈니스 로직의 진입 지점으로, 다음과 같은 작업을 수행한다.
-
요청 파라미터 처리
-
필요한 Model 호출 (데이터 조회/저장 등)
-
적절한 Template에 데이터 전달
-
-
예:
-
Django의
views.py의 함수/클래스 기반 뷰 -
Flask의 라우트 함수(
@app.route또는 Blueprint의 뷰 함수)
-
HTML 간단 소개
HTML은 태그(tag)를 이용해 문서 구조를 표현하는 마크업 언어이다.
HTML 문서는 트리 구조(Tree Structure)로 구성되며, 가장 상위 루트는 <html> 태그이다.
HTML 문서 구조
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
</body>
</html>
| 구조 | 설명 |
|---|---|
<!DOCTYPE html> |
HTML5 문서임을 선언 |
<html> |
HTML 문서의 최상위 루트 노드 |
<head> |
문서 설정 정보(메타데이터) 포함 |
<body> |
실제 화면에 보여지는 콘텐츠 영역 |
트리 구조 표현 (DOM 구조)
html
├── head
│ ├── meta
│ ├── title
│ ├── link
│ └── script
└── body
├── header
├── nav
├── section
├── article
├── div
├── footer
├── script
│
...
head 영역에 들어가는 주요 태그
| 태그 | 설명 |
|---|---|
<meta> |
문자 인코딩, SEO, 모바일 설정 등 |
<title> |
웹페이지 제목 (브라우저 탭에 표시됨) |
<link> |
CSS 파일 연결 |
<script> |
JavaScript 연결 |
<style> |
내부 CSS 작성 |
body 영역에서 자주 사용하는 태그
| 태그 | 의미 |
|---|---|
<h1> ~ <h6> |
제목(Heading) |
<p> |
문단(paragraph) |
<a> |
링크(anchor) |
<img> |
이미지 |
<ul> / <ol> / <li> |
리스트 |
<div> |
블록 단위 영역 |
<span> |
인라인 영역 |
<form> |
사용자 입력 양식 |
<input> |
데이터 입력 필드 |
<label> |
입력 필드 설명 텍스트, for-id 연결로 포커스 이동·접근성 향상 |
<button> |
버튼 |
<table> |
표 구조 |
프로젝트 구조
project/
│
├─ config.py # 시스템 설정
├─ server/
│ ├─ __init__.py # 서버 초기화
│ ├─ models.py # DB 정의/설정
│ ├─ views.py # 라우트 정의
│ └─ templates/ # 템플릿 저장소
│ └─ index.html # 랜딩 페이지
└─ run_server.py # 서버 구동(시작)
시스템 설정
config.py:
# project/config.py
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = "dev-secret-key"
SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(BASE_DIR, 'hello.db')}"
SQLALCHEMY_TRACK_MODIFICATIONS = False
서버 초기화
__init__.py: Flask 앱을 생성하고 SQLAlchemy DB, Blueprint 뷰를 등록하는 초기화 함수 정의
# project/server/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import Config
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
from . import models
from .views import main
app.register_blueprint(main)
with app.app_context():
db.create_all()
return app
DB 정의/설정
models.py: SQLAlchemy를 사용해 User 테이블의 구조(id, username, email)와 동작을 정의하는 DB 모델
# project/server/models.py
from . import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=False, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"<User {self.username}>"
라우트 정의
views.py: GET 요청으로 폼을 표시하고, POST 요청으로 사용자 정보를 DB에 저장한 후 결과를 반환하는 라우트 함수들 정의
python# project/server/views.py
from flask import Blueprint, render_template, request, redirect, url_for
from . import db
from .models import User
main = Blueprint("main", __name__)
@main.route("/", methods=["GET"])
def index():
return render_template("index.html")
@main.route("/submit", methods=["POST"])
def submit():
username = request.form.get("username")
email = request.form.get("email")
new_user = User(username=username, email=email)
db.session.add(new_user)
db.session.commit()
return redirect(url_for("main.result", username=username, email=email))
@main.route("/result", methods=["GET"])
def result():
username = request.args.get("username")
email = request.args.get("email")
return f"User {username} with email {email} has been added to the database."
랜딩 페이지 작성
templates/index.html: username과 email 입력 필드를 가진 HTML 폼으로, submit 버튼 클릭 시 POST 요청을 views의 submit 라우트로 전송
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Form</title>
</head>
<body>
<h1>Enter your details</h1>
<form action="{{ url_for('main.submit') }}" method="POST">
<label for="username">Name:</label><br>
<input type="text" id="username" name="username" required><br>
<label for="email">Email:</label><br>
<input type="email" id="email" name="email" required><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
서버 구동 모듈
run_server.py: create_app() 함수로 Flask 애플리케이션을 생성하고 포트8080에서 debug 모드로 서버를 실행
# project/run_server.py
from server import create_app
app = create_app()
if __name__ == "__main__":
app.run(port=8080, debug=True)
웹 서버 실행
run_server.py 파일을 실행하면 Flask 애플리케이션이 시작되어 http://localhost:8080에서 웹 서버가 실행된다.
python project/run_server.py
# 또는
cd project
python run_server.py