2026 年に FastAPI を使用する理由

FastAPI は、わずか数年で実験プロジェクトから API のリファレンス フレームワークにまでスケールアップしました。 Python は本番環境にあります。 Python Developers Survey 2024 によると、これは 2 番目のフレームワークです Python Web の普及率 (38%) を上回ったのは Django のみでした。理由は具体的です: パフォーマンス I/O バウンドのワークロードに対して Node.js や Go に匹敵し、ボイラープレートなしのデータ検証を使用します。 Pydantic v2 および OpenAPI ドキュメントはコードから自動的に生成されます。

その秘密はアーキテクチャにあります。FastAPI は以下に基づいて構築されています。 スターレット (ASGI フレームワーク) e ピダンティック (Rustコアで検証)。追加されません 役に立たない抽象化 - すべての機能には正確な技術的理由があります。

何を学ぶか

  • インストールと最初の FastAPI サーバーの実行が 5 分で完了
  • Python の型ヒントが検証、シリアル化、ドキュメント化される仕組み
  • Pydantic を使用したパス パラメーター、クエリ パラメーター、およびリクエスト本文
  • Swagger UI と ReDoc: 自動生成されたドキュメントをナビゲートする
  • ステータスコード、応答モデル、および基本的なエラー処理
  • 実際の FastAPI プロジェクトの構造 (単一のファイルだけではない)

インストールと最初のサーバー

FastAPI には Python 3.8 以降が必要ですが、パフォーマンスを向上させるために 3.11 以降をお勧めします asyncio と型ヒントの新機能。 Uvicorn は ASGI サーバーです ローカル開発に推奨されます。

# Ambiente virtuale (sempre, mai installare globalmente)
python -m venv .venv
source .venv/bin/activate  # Linux/Mac
# .venv\Scripts\activate  # Windows

# Installazione dipendenze core
pip install fastapi uvicorn[standard]

# Per sviluppo aggiungere anche:
pip install httpx pytest pytest-asyncio

# Verifica installazione
python -c "import fastapi; print(fastapi.__version__)"
# 0.115.x

可能な最小限のサーバー。これを名前を付けて保存 main.py:

# main.py - Il server FastAPI piu semplice possibile
from fastapi import FastAPI

# Crea l'istanza dell'applicazione
# title e description appaiono nella documentazione Swagger
app = FastAPI(
    title="La Mia API",
    description="API costruita con FastAPI e Python type hints",
    version="1.0.0",
)

# Decorator che registra la route GET /
@app.get("/")
def read_root():
    # Il dict viene automaticamente serializzato in JSON
    return {"message": "Hello, FastAPI!", "status": "running"}

# Avvio con: uvicorn main:app --reload
# main = nome del file, app = variabile FastAPI, --reload = hot reload
# Avvia il server con hot reload (ricrea il server ad ogni modifica)
uvicorn main:app --reload

# Output:
# INFO:     Will watch for changes in these directories: ['/path/to/project']
# INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
# INFO:     Started reloader process [12345]
# INFO:     Started server process [12346]
# INFO:     Waiting for application startup.
# INFO:     Application startup complete.

開ける http://127.0.0.1:8000/docs 生成された Swagger UI を確認するには 自動的に。何も設定していません: FastAPI がコードの注釈を読み取りました そして完全なドキュメントを生成しました。

API コントラクトとしてのタイプヒント

FastAPI の最も強力な機能は、次のような Python 型ヒントの使用です。 API コントラクトの定義。注釈付きの各パラメータは自動的に次のようになります。 検証され、文書化され、シリアル化されます。追加の定型コードはゼロです。

# routes/users.py - Esempi di parametri con type hints
from fastapi import FastAPI, Path, Query, HTTPException
from typing import Optional
from pydantic import BaseModel, EmailStr, Field
from datetime import datetime

app = FastAPI()

# --- PATH PARAMETERS ---
# Il tipo int fa si che FastAPI validi che userId sia un intero
@app.get("/users/{user_id}")
def get_user(
    user_id: int,  # Path parameter: automaticamente estratto dall'URL
):
    if user_id <= 0:
        raise HTTPException(status_code=400, detail="user_id must be positive")
    return {"user_id": user_id, "name": f"User {user_id}"}

# Path con validazione avanzata tramite Path()
@app.get("/items/{item_id}")
def get_item(
    item_id: int = Path(
        title="The ID of the item",
        description="Must be a positive integer",
        ge=1,       # greater than or equal to 1
        le=1000,    # less than or equal to 1000
    ),
):
    return {"item_id": item_id}

# --- QUERY PARAMETERS ---
# Parametri con default = opzionali, senza default = obbligatori
@app.get("/search")
def search_users(
    q: str,                          # Obbligatorio (no default)
    page: int = 1,                   # Opzionale con default
    limit: int = Query(default=10, ge=1, le=100),  # Con validazione
    active_only: bool = True,        # Bool viene da "true"/"false" nella query string
    role: Optional[str] = None,      # Opzionale, None se non fornito
):
    return {
        "query": q,
        "page": page,
        "limit": limit,
        "active_only": active_only,
        "role": role,
    }
    # GET /search?q=mario&page=2&limit=20&active_only=false&role=admin

Pydantic モデルを使用したリクエスト本文

POST/PUT/PATCH リクエストの本文のデータには、Pydantic テンプレートが使用されます。 FastAPI は、受信した JSON を自動的に逆シリアル化して、テンプレートに対して検証し、 そしてそれを型付きの Python オブジェクトとして利用できるようにします。

# models/user.py - Definizione dei modelli con Pydantic v2
from pydantic import BaseModel, EmailStr, Field, field_validator
from typing import Optional
from enum import Enum

class UserRole(str, Enum):
    admin = "admin"
    editor = "editor"
    viewer = "viewer"

# Modello per la creazione di un utente (in input)
class UserCreate(BaseModel):
    name: str = Field(
        min_length=2,
        max_length=100,
        description="Full name of the user",
        examples=["Mario Rossi"],
    )
    email: EmailStr  # Validazione email inclusa in Pydantic
    role: UserRole = UserRole.viewer  # Default al valore meno privilegiato
    age: Optional[int] = Field(default=None, ge=0, le=150)

    # Validator personalizzato (Pydantic v2 syntax)
    @field_validator("name")
    @classmethod
    def name_must_contain_space(cls, v: str) -> str:
        if " " not in v:
            raise ValueError("name must contain at least first and last name")
        return v.strip()

# Modello per la risposta (include campi generati dal server)
class UserResponse(BaseModel):
    id: int
    name: str
    email: EmailStr
    role: UserRole
    created_at: str  # ISO 8601

# Route POST che usa i modelli
@app.post(
    "/users",
    response_model=UserResponse,  # Definisce la struttura della risposta
    status_code=201,               # HTTP 201 Created
    summary="Create a new user",
    tags=["users"],
)
def create_user(user: UserCreate):
    # user e gia validato e typed come UserCreate
    # FastAPI ha deserializzato il JSON e verificato tutti i vincoli
    new_user = {
        "id": 42,  # In realta verrebbe dal database
        "name": user.name,
        "email": user.email,
        "role": user.role.value,
        "created_at": "2026-06-01T10:00:00Z",
    }
    return new_user
    # Solo i campi di UserResponse vengono inclusi nella risposta
    # (response_model filtra automaticamente campi extra come password hash)

HTTPException によるエラー処理

FastAPI は、例外を構造化された HTTP 応答にマッピングします。標準パターンでは、 HTTPException 予期されるエラーとグローバル例外ハンドラ用 予期しないエラー。

# Errori standard con HTTPException
from fastapi import HTTPException, status

@app.get("/users/{user_id}", response_model=UserResponse)
def get_user(user_id: int):
    user = db.find_user(user_id)  # Ipotetica funzione DB

    if user is None:
        # status.HTTP_404_NOT_FOUND = 404 (uso le costanti, piu leggibile)
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"User with id {user_id} not found",
        )

    return user

# Exception handler globale per errori non gestiti
from fastapi import Request
from fastapi.responses import JSONResponse

@app.exception_handler(Exception)
async def generic_exception_handler(request: Request, exc: Exception):
    # Log l'errore (NON esporre il dettaglio in produzione)
    import logging
    logging.error(f"Unhandled exception: {exc}", exc_info=True)

    return JSONResponse(
        status_code=500,
        content={"detail": "Internal server error"},
    )

実際のプロジェクトの構造

シングル main.py チュートリアルには問題ありませんが、実際のプロジェクトには適していません。 推奨される構造では、懸念事項がまとまったモジュールに分割されます。

# Struttura consigliata per un progetto FastAPI medio
my_api/
├── app/
│   ├── __init__.py
│   ├── main.py              # Entry point: crea l'app FastAPI e include i router
│   ├── config.py            # Configurazione (env vars, Settings con Pydantic)
│   ├── database.py          # Connessione DB, session factory
│   ├── models/
│   │   ├── __init__.py
│   │   ├── user.py          # SQLAlchemy ORM models
│   │   └── item.py
│   ├── schemas/             # Pydantic models (request/response)
│   │   ├── __init__.py
│   │   ├── user.py          # UserCreate, UserUpdate, UserResponse
│   │   └── item.py
│   ├── routers/             # APIRouter per ogni dominio
│   │   ├── __init__.py
│   │   ├── users.py         # /users endpoints
│   │   └── items.py         # /items endpoints
│   ├── services/            # Business logic (separata dai router)
│   │   ├── user_service.py
│   │   └── item_service.py
│   └── dependencies.py      # Depends() condivise (auth, DB session)
├── tests/
│   ├── conftest.py
│   ├── test_users.py
│   └── test_items.py
├── alembic/                 # Migrations DB
├── pyproject.toml
└── docker-compose.yml
# app/main.py - Entry point con router modulari
from fastapi import FastAPI
from app.routers import users, items
from app.config import get_settings

settings = get_settings()

app = FastAPI(
    title=settings.APP_NAME,
    version=settings.APP_VERSION,
    docs_url="/docs" if settings.DEBUG else None,  # Disabilita docs in produzione
    redoc_url="/redoc" if settings.DEBUG else None,
)

# Include i router con prefisso e tag per la documentazione
app.include_router(users.router, prefix="/users", tags=["users"])
app.include_router(items.router, prefix="/items", tags=["items"])

@app.get("/health", tags=["system"])
def health_check():
    return {"status": "healthy", "version": settings.APP_VERSION}

OpenAPI ドキュメント: Swagger と ReDoc

FastAPI は、アクセスできる 2 つのインタラクティブなドキュメント インターフェイスを自動的に生成します。 開発中:

  • Swagger UI (/docs): テスト用の対話型インターフェイス ブラウザから直接 API を使用できます。認証、JSON 本文、クエリ パラメーターをサポートします。
  • 再ドキュメント (/redoc): 読みやすいドキュメント。次の用途に最適です。 チームまたは API コンシューマーと共有します。
  • OpenAPI JSON (/openapi.json): 機械可読スキーマ 任意の言語で SDK クライアントを生成するために使用されます。
# Arricchire la documentazione con metadata aggiuntivi
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi

app = FastAPI()

# Override del schema OpenAPI per aggiungere security schemes e metadata
def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema

    openapi_schema = get_openapi(
        title="My API",
        version="2.0.0",
        description="Descrizione lunga dell'API con **markdown** supportato",
        terms_of_service="https://example.com/terms",
        contact={
            "name": "Federico Calo",
            "url": "https://federicocalo.dev",
            "email": "info@federicocalo.dev",
        },
        license_info={
            "name": "MIT",
            "url": "https://opensource.org/licenses/MIT",
        },
        routes=app.routes,
    )

    # Aggiungi Bearer token authentication
    openapi_schema["components"]["securitySchemes"] = {
        "BearerAuth": {
            "type": "http",
            "scheme": "bearer",
            "bearerFormat": "JWT",
        }
    }

    app.openapi_schema = openapi_schema
    return app.openapi_schema

app.openapi = custom_openapi

本番環境でのドキュメント

実稼働環境では設定により Swagger UI と ReDoc を常に無効にします docs_url=None e redoc_url=None FastAPI コンストラクター内。 インタラクティブなドキュメントでは、API の内部構造が公開されており、 文書化されていないエンドポイントを探索するために使用されます。エンドポイント /openapi.json 同じ方法で保護する必要があります。

Pydantic 設定による構成

FastAPI で設定を処理する正しい方法は、次のとおりです。 pydantic-settings 環境変数を自動的に読み取ります 型検証あり:

# app/config.py - Configurazione type-safe con pydantic-settings
# pip install pydantic-settings
from pydantic_settings import BaseSettings, SettingsConfigDict
from functools import lru_cache

class Settings(BaseSettings):
    # Valori letti da variabili d'ambiente (case insensitive)
    APP_NAME: str = "My FastAPI App"
    APP_VERSION: str = "1.0.0"
    DEBUG: bool = False

    # Database
    DATABASE_URL: str  # Obbligatorio: fallisce se non presente
    DB_POOL_SIZE: int = 10
    DB_MAX_OVERFLOW: int = 20

    # Secrets
    SECRET_KEY: str  # Obbligatorio
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 30

    # CORS
    ALLOWED_ORIGINS: list[str] = ["http://localhost:3000"]

    model_config = SettingsConfigDict(
        env_file=".env",           # Legge da .env se presente
        env_file_encoding="utf-8",
        case_sensitive=False,      # DATABASE_URL = database_url
    )

# lru_cache evita di rileggere il file .env ad ogni richiesta
@lru_cache
def get_settings() -> Settings:
    return Settings()

# Uso nelle route tramite Depends()
from fastapi import Depends

@app.get("/info")
def app_info(settings: Settings = Depends(get_settings)):
    return {
        "name": settings.APP_NAME,
        "version": settings.APP_VERSION,
        "debug": settings.DEBUG,
    }

結論と次のステップ

FastAPI は、開発速度、開発速度、開発速度、 タイプの安全性とパフォーマンス。型ヒントは装飾的なものではなく、検証を促進します。 文書化と自動シリアル化。これによりコードが大幅に削減されます Flask または Django REST フレームワークと比較した定型文。

次のステップは、FastAPI を高速にする非同期モデルを理解することです。 I/O バウンドのワークロード: asyncio、イベント ループ、コルーチンの仕組みとそれらをいつ使用するか async def vs def 普通。

Python FastAPI と非同期 Web シリーズ

  • 第 1 条 (本): セットアップ、入力ヒント、OpenAPI セルフドキュメンテーション
  • 第2条: Python の Async/Await: イベント ループ、コルーチン、および I/O バインドされた同時実行性
  • 第3条: Pydantic v2: 高度な検証、BaseModel および TypeAdapter
  • 第4条: 依存関係の注入: クリーンでテスト可能なコードのパターン
  • 第5条: SQLAlchemy 2.0 と Alembic を使用した非同期データベース