Python은 다양한 웹 프레임워크를 제공하며, 그중 FastAPI, Django, Flask는 가장 널리 사용되는 프레임워크입니다. 이 글에서는 각 프레임워크의 장단점, 활용 사례, 그리고 간단한 예제 코드를 통해 비교해보겠습니다. 이를 통해 여러분의 프로젝트에 적합한 프레임워크를 선택하는 데 도움을 드리고자 합니다.
1. 프레임워크 개요
프레임워크 | 출시연도 | 특징 | 주요 장점 | 주요 단점 |
---|---|---|---|---|
Django | 2005 | 풀스택 웹 프레임워크 | 강력한 ORM, 관리자 인터페이스 제공 | 무겁고 설정 복잡 |
Flask | 2010 | 마이크로 프레임워크 | 경량, 유연성, 확장성 | 기본 제공 기능 부족 |
FastAPI | 2018 | 비동기 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 라우팅, 뷰 작성이 체계적입니다.
프로젝트 구조
textmyproject/ ├── myapp/ │ ├── models.py │ ├── views.py │ ├── urls.py │ ├── serializers.py │ └── admin.py └── myproject/ ├── settings.py ├── urls.py
코드
models.py
(데이터베이스 모델 정의)
pythonfrom 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
(데이터 직렬화)
pythonfrom rest_framework import serializers from .models import User class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id', 'name', 'email']
views.py
(API 뷰 작성)
pythonfrom 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
(라우팅 설정)
pythonfrom django.urls import path from .views import UserListCreateAPIView urlpatterns = [ path('users/', UserListCreateAPIView.as_view()), ]
Flask 예제
Flask는 경량 프레임워크로 ORM이나 데이터 검증 기능을 제공하지 않으므로, 이를 위해 추가 라이브러리(SQLAlchemy, Marshmallow 등)를 사용합니다.
프로젝트 구조
textmyflaskapp/ ├── app.py ├── models.py └── schemas.py
코드
models.py
(SQLAlchemy 모델 정의)
pythonfrom 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로 데이터 직렬화 및 검증)
pythonfrom 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 애플리케이션 작성)
pythonfrom 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을 간소화하며 비동기 프로그래밍을 지원합니다.
프로젝트 구조
textmyfastapiapp/ ├── main.py ├── models.py └── schemas.py
코드
models.py
(SQLAlchemy 모델 정의)
pythonfrom 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으로 데이터 검증 및 직렬화)
pythonfrom 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 애플리케이션 작성)
pythonfrom 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 서비스 (머신러닝 모델 서빙 등) |
프레임워크 선택은 프로젝트 요구사항과 팀의 기술 스택에 따라 달라집니다.