레이블이 Flask인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Flask인 게시물을 표시합니다. 모든 게시물 표시

20250103

Python 프레임워크 비교: FastAPI vs Django vs Flask

Python은 다양한 웹 프레임워크를 제공하며, 그중 FastAPIDjangoFlask는 가장 널리 사용되는 프레임워크입니다. 이 글에서는 각 프레임워크의 장단점, 활용 사례, 그리고 간단한 예제 코드를 통해 비교해보겠습니다. 이를 통해 여러분의 프로젝트에 적합한 프레임워크를 선택하는 데 도움을 드리고자 합니다.

1. 프레임워크 개요

프레임워크출시연도특징주요 장점주요 단점
Django2005풀스택 웹 프레임워크강력한 ORM, 관리자 인터페이스 제공무겁고 설정 복잡
Flask2010마이크로 프레임워크경량, 유연성, 확장성기본 제공 기능 부족
FastAPI2018비동기 API 중심 프레임워크높은 성능, 자동 문서화커뮤니티 및 리소스 부족

2. 주요 기능 비교

a. 성능

FastAPI는 비동기 프로그래밍(ASGI 기반)을 지원하여 높은 성능을 자랑합니다. 반면, Django와 Flask는 동기 프로그래밍(WSGI 기반)을 기본으로 하며, Django는 최근 ASGI를 지원하기 시작했습니다.

  • 벤치마크 결과 (RPS 기준):
    • FastAPI: 76.1 req/s
    • Django: 72 req/s
    • Flask: 70.8 req/s

b. 데이터 유효성 검증

  • Django: Forms와 DRF Serializers를 사용.
  • Flask: 별도의 라이브러리(WTForms 등) 필요.
  • FastAPI: Pydantic을 사용해 타입 힌팅과 데이터 검증을 간소화.

c. API 설계

  • Django: REST API 설계 시 Django REST Framework(DRF)를 추가로 사용.
  • Flask: RESTful API를 위해 Flask-RESTful 같은 확장이 필요.
  • FastAPI: 기본적으로 Pydantic과 OpenAPI를 통해 API 설계 및 문서화를 지원.

3. 예제 코드 비교

다음은 간단한 "사용자 관리 API"를 세 프레임워크로 구현한 예제입니다. 각 예제는 사용자 목록 조회와 새로운 사용자 추가 기능을 포함합니다.

Django 예제

Django는 강력한 ORM과 내장 기능을 제공하므로, 모델 정의와 URL 라우팅, 뷰 작성이 체계적입니다.

프로젝트 구조

text
myproject/ ├── myapp/ │ ├── models.py │ ├── views.py │ ├── urls.py │ ├── serializers.py │ └── admin.py └── myproject/ ├── settings.py ├── urls.py

코드

models.py (데이터베이스 모델 정의)

python
from django.db import models class User(models.Model): name = models.CharField(max_length=100) email = models.EmailField(unique=True) def __str__(self): return self.name

serializers.py (데이터 직렬화)

python
from rest_framework import serializers from .models import User class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id', 'name', 'email']

views.py (API 뷰 작성)

python
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .models import User from .serializers import UserSerializer class UserListCreateAPIView(APIView): def get(self, request): users = User.objects.all() serializer = UserSerializer(users, many=True) return Response(serializer.data) def post(self, request): serializer = UserSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

urls.py (라우팅 설정)

python
from django.urls import path from .views import UserListCreateAPIView urlpatterns = [ path('users/', UserListCreateAPIView.as_view()), ]

Flask 예제

Flask는 경량 프레임워크로 ORM이나 데이터 검증 기능을 제공하지 않으므로, 이를 위해 추가 라이브러리(SQLAlchemy, Marshmallow 등)를 사용합니다.

프로젝트 구조

text
myflaskapp/ ├── app.py ├── models.py └── schemas.py

코드

models.py (SQLAlchemy 모델 정의)

python
from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) def __repr__(self): return f'<User {self.name}>'

schemas.py (Marshmallow로 데이터 직렬화 및 검증)

python
from marshmallow import Schema, fields class UserSchema(Schema): id = fields.Int(dump_only=True) name = fields.Str(required=True) email = fields.Email(required=True)

app.py (Flask 애플리케이션 작성)

python
from flask import Flask, request, jsonify from models import db, User from schemas import UserSchema app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db' db.init_app(app) user_schema = UserSchema() users_schema = UserSchema(many=True) @app.route('/users', methods=['GET']) def get_users(): users = User.query.all() return jsonify(users_schema.dump(users)) @app.route('/users', methods=['POST']) def create_user(): data = request.json errors = user_schema.validate(data) if errors: return jsonify(errors), 400 new_user = User(name=data['name'], email=data['email']) db.session.add(new_user) db.session.commit() return user_schema.dump(new_user), 201 if __name__ == '__main__': with app.app_context(): db.create_all() # 데이터베이스 초기화 app.run(debug=True)

FastAPI 예제

FastAPI는 Pydantic과 SQLAlchemy를 활용하여 데이터 검증과 ORM을 간소화하며 비동기 프로그래밍을 지원합니다.

프로젝트 구조

text
myfastapiapp/ ├── main.py ├── models.py └── schemas.py

코드

models.py (SQLAlchemy 모델 정의)

python
from sqlalchemy import Column, Integer, String, create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker Base = declarative_base() engine = create_engine('sqlite:///users.db') SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True, index=True) name = Column(String(100), nullable=False) email = Column(String(120), unique=True, nullable=False) Base.metadata.create_all(bind=engine)

schemas.py (Pydantic으로 데이터 검증 및 직렬화)

python
from pydantic import BaseModel, EmailStr class UserBase(BaseModel): name: str email: EmailStr class UserCreate(UserBase): pass class UserResponse(UserBase): id: int class Config: orm_mode = True # ORM 객체를 Pydantic 모델로 변환 가능하게 설정

main.py (FastAPI 애플리케이션 작성)

python
from fastapi import FastAPI, Depends, HTTPException from sqlalchemy.orm import Session from models import SessionLocal, User from schemas import UserCreate, UserResponse app = FastAPI() # 의존성 주입: 데이터베이스 세션 생성 및 종료 관리 def get_db(): db = SessionLocal() try: yield db finally: db.close() @app.get("/users", response_model=list[UserResponse]) async def get_users(db: Session = Depends(get_db)): users = db.query(User).all() return users @app.post("/users", response_model=UserResponse, status_code=201) async def create_user(user: UserCreate, db: Session = Depends(get_db)): if db.query(User).filter(User.email == user.email).first(): raise HTTPException(status_code=400, detail="Email already registered") new_user = User(name=user.name, email=user.email) db.add(new_user) db.commit() db.refresh(new_user) # 새로 추가된 객체 반환 return new_user

4. 추천 활용 사례 및 결론

프레임워크적합한 프로젝트 유형
Django대규모 웹 애플리케이션 (전자상거래 플랫폼 등)
Flask소규모 프로젝트 및 프로토타입
FastAPI고성능 API 서비스 (머신러닝 모델 서빙 등)

프레임워크 선택은 프로젝트 요구사항과 팀의 기술 스택에 따라 달라집니다.