近年、Python開発の世界では真の革命が起こっています。多くのチームが新しいプロジェクトにFastAPIを選択し、長年にわたって業界標準となっていたフレームワークであるDjangoを徐々に置き換えています。何が起こっているのか、そしてなぜ初心者の開発者がFastAPIに注目すべきなのかを理解しましょう。
FastAPIとDjangoとは何ですか?
Django は、2005年から存在するフル機能のWebフレームワークです。これは、組み込みの管理パネル、ORM、テンプレートシステム、およびその他の多くの「すぐに使える」機能を備えた本格的なWebアプリケーションを開発するために作成されました。
FastAPI — 2018年に登場した、API開発専用の最新フレームワーク。これは、Python 3.7+の最新機能と非同期プログラミングに基づいて構築されています。
FastAPIが人気を集めている理由は?
1. Go や Node.js 並みのパフォーマンス
FastAPI は、非同期性により最も高速な Python フレームワークの 1 つです。以下は簡単な比較です。
# Django(同期アプローチ)
from django.http import JsonResponse
def get_users(request):
users = User.objects.all() # ブロックリクエスト
return JsonResponse({'users': list(users.values())})CODE_BLOCK_1__💡 重要: FastAPI では、クエリは非同期で処理されるため、サーバーはロックなしで同時に数千の接続を処理できます。Djangoもバージョン3.1以降で非同期をサポートしていますが、エコシステムはまだ完全には適応されていません。
2. 信じられないほど簡単なスタート
FastAPI で最初の API を作成するには、文字通り 5 分で作成できます。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello, world!"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}次のコマンドを実行します。
uvicorn main:app --reload✅ これで完了です!APIが動作するようになりました。設定、構成ファイル、複雑なプロジェクト構造はありません。
3. 自動ドキュメントは魔法です
FastAPIの最も優れた機能の1つは、自動インタラクティブドキュメントです。http://localhost:8000/docsを開くだけで、ブラウザで各エンドポイントをテストできる完全なSwagger UIドキュメントが表示されます。
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI(
title="My project's API",
description="Description of all endpoints",
version="1.0.0"
)
class Item(BaseModel):
name: str
description: str = None
price: float
@app.post("/items/")
async def create_item(item: Item):
"""
Creating a new product:
- **name**: product name
- **description**: description (optional)
- **price**: product price
"""
return {"item": item}ドキュメントは、データ型とドキュメント文字列から自動的に生成されます。Djangoでは、これを行うには、drf-spectacularのような追加ライブラリを使用する必要があります。
4. 箱からの型付けと検証
FastAPIはPydanticを使用してデータを自動的に検証します。
from pydantic import BaseModel, EmailStr, validator
from typing import Optional
class User(BaseModel):
username: str
email: EmailStr
age: Optional[int] = None
@validator('age')
def age_must_be_positive(cls, v):
if v is not None and v < 0:
raise ValueError('Age cannot be negative')
return v
@app.post("/users/")
async def create_user(user: User):
# データが無効な場合、FastAPI は自動的に 422 エラーを返します
# 問題の詳細な説明
return {"user": user}無効なデータを送信すると、すべての問題を示すわかりやすいエラーが表示されます。
5.依存関係に関する現代の仕事
FastAPI の依存関係の注入により、コードがクリーンでテスト可能になります。
from fastapi import Depends, HTTPException
from sqlalchemy.orm import Session
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
def get_current_user(token: str = Header(...)):
user = verify_token(token)
if not user:
raise HTTPException(status_code=401, detail="Unauthorized")
return user
@app.get("/users/me")
async def read_current_user(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
return current_user依存関係は自動的に解決され、注入されます。これにより、テストが非常に簡単になります。
6. WebSocketとバックグラウンドタスク
from fastapi import WebSocket, BackgroundTasks
import time
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Received: {data}")
def write_log(message: str):
time.sleep(5) # 長時間の手術
with open("log.txt", "a") as f:
f.write(message)
@app.post("/send-notification/")
async def send_notification(
email: str,
background_tasks: BackgroundTasks
):
background_tasks.add_task(write_log, f"Sent to {email}")
return {"message": "Notification will be sent"}
Djangoを選択するのはいつですか?
FastAPI が常に最良の選択肢であるとは限りません。必要に応じて、Django を優先します。
管理パネルを備えた本格的なウェブアプリケーション — 箱から出されたばかりのDjango Admin
認証と許可のシステム — 完成済みで、長期にわたって実績がある
移行を伴うORM — 初心者にとってDjango ORMは簡単です
組み込みテンプレートシステム — サーバーサイドレンダリングが必要な場合
巨大なパッケージのエコシステム — Djangoは19年前から存在しています
実例: CRUD API
タスクを管理するための簡単なCRUD APIを作成しましょう。
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
from datetime import datetime
app = FastAPI()
class Task(BaseModel):
id: Optional[int] = None
title: str
description: Optional[str] = None
completed: bool = False
created_at: Optional[datetime] = None
# 一時ストレージ(実際にはデータベースを使用してください)
tasks_db = []
task_id_counter = 1
@app.post("/tasks/", response_model=Task)
async def create_task(task: Task):
global task_id_counter
task.id = task_id_counter
task.created_at = datetime.now()
task_id_counter += 1
tasks_db.append(task)
return task
@app.get("/tasks/", response_model=List[Task])
async def get_tasks(completed: Optional[bool] = None):
if completed is None:
return tasks_db
return [t for t in tasks_db if t.completed == completed]
@app.get("/tasks/{task_id}", response_model=Task)
async def get_task(task_id: int):
task = next((t for t in tasks_db if t.id == task_id), None)
if not task:
raise HTTPException(status_code=404, detail="Task not found")
return task
@app.put("/tasks/{task_id}", response_model=Task)
async def update_task(task_id: int, task_update: Task):
task = next((t for t in tasks_db if t.id == task_id), None)
if not task:
raise HTTPException(status_code=404, detail="Task not found")
task.title = task_update.title
task.description = task_update.description
task.completed = task_update.completed
return task
@app.delete("/tasks/{task_id}")
async def delete_task(task_id: int):
global tasks_db
tasks_db = [t for t in tasks_db if t.id != task_id]
return {"message": "Task deleted"}データベースとの統合
FastAPIはSQLAlchemyとの相性が抜群です。
from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./tasks.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class TaskModel(Base):
__tablename__ = "tasks"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(String)
completed = Column(Boolean, default=False)
Base.metadata.create_all(bind=engine)
@app.post("/tasks/", response_model=Task)
async def create_task(task: Task, db: Session = Depends(get_db)):
db_task = TaskModel(**task.dict(exclude={'id'}))
db.add(db_task)
db.commit()
db.refresh(db_task)
return db_task認証とセキュリティ
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from passlib.context import CryptContext
from jose import JWTError, jwt
from datetime import datetime, timedelta
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=30)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
user = authenticate_user(form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials"
)
access_token = create_access_token(data={"sub": user.username})
return {"access_token": access_token, "token_type": "bearer"}
async def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise HTTPException(status_code=401)
return username
except JWTError:
raise HTTPException(status_code=401)
@app.get("/users/me")
async def read_users_me(current_user: str = Depends(get_current_user)):
return {"username": current_user}テスト
FastAPIはテストを簡単にします。
from fastapi.testclient import TestClient
client = TestClient(app)
def test_create_task():
response = client.post(
"/tasks/",
json={"title": "Test task", "description": "Description"}
)
assert response.status_code == 200
assert response.json()["title"] == "Test task"
def test_get_tasks():
response = client.get("/tasks/")
assert response.status_code == 200
assert isinstance(response.json(), list)パフォーマンス:数字と事実
TechEmpower Benchmarks (2026)によると:
フレームワーク | 1秒あたりのリクエスト数 | 生産性 |
|---|---|---|
FastAPI | ~60,000 | ⭐⭐⭐⭐⭐ |
Django Ninja | ~40,000 | ⭐⭐⭐⭐ |
Django + gunicorn | ~10,000 | ⭐⭐⭐ |
🚀 結論: FastAPIは、同じ負荷で6倍のリクエストを処理できます。
B コディケ Python、FastAPI、Django、その他の最新テクノロジーに関する詳細なコースが見つかります。実際のプロジェクトとわかりやすい説明を通して、プログラミングを実践的に学びます。
🚀 私たちの Telegramチャンネル — ここには、フレンドリーな開発者コミュニティ、役立つ資料、コード分析、質問への回答があります。私たちはあなたが需要のある専門家になるのを助けます!
コディックでプログラミングの旅を始めましょう。快適に、迅速に、そして効率的に学びましょう!
