2026년에 FastAPI를 사용해야 하는 이유

FastAPI는 불과 몇 년 만에 실험 프로젝트에서 API용 참조 프레임워크로 확장되었습니다. Python을 생산 중입니다. Python Developers Survey 2024에 따르면 이는 두 번째 프레임워크입니다. 확산 기준 Python 웹(38%)은 Django만이 능가합니다. 그 이유는 구체적입니다: 성능 I/O 바인딩 워크로드의 경우 Node.js 및 Go와 유사하며 상용구가 필요 없는 데이터 검증 Pydantic v2 및 OpenAPI 문서는 코드에서 자동으로 생성됩니다.

비밀은 건축적입니다. FastAPI는 다음을 기반으로 합니다. 별표 (ASGI 프레임워크) e 피단틱 (Rust 코어를 사용한 검증). 추가되지 않습니다 쓸모없는 추상화 — 모든 기능에는 정확한 기술적 이유가 있습니다.

무엇을 배울 것인가

  • 5분 안에 설치 및 첫 번째 FastAPI 서버 실행
  • 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는 사용자가 방문할 수 있는 두 개의 대화형 문서 인터페이스를 자동으로 생성합니다. 개발 중:

  • 스웨거 UI (/docs): 테스트를 위한 대화형 인터페이스 브라우저에서 직접 API. 인증, JSON 본문, 쿼리 매개변수를 지원합니다.
  • 재독 (/redoc): 읽을 수 있는 문서로, 다음에 적합합니다. 팀이나 API 소비자와 공유하세요.
  • 오픈API 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 Framework와 비교한 상용구입니다.

다음 단계는 FastAPI를 빠르게 만드는 비동기 모델을 이해하는 것입니다. I/O 바인딩 워크로드: asyncio, 이벤트 루프 및 코루틴 작동 방식 및 사용 시기 async def vs def 정상.

Python FastAPI 및 Async 웹 시리즈

  • 제1조(본): 설정, 유형 힌트 및 OpenAPI 자체 문서
  • 제2조: Python의 Async/Await: 이벤트 루프, 코루틴 및 I/O 바인딩 동시성
  • 제3조: Pydantic v2: 고급 검증, BaseModel 및 TypeAdapter
  • 제4조: 종속성 주입: 깨끗하고 테스트 가능한 코드를 위한 패턴
  • 제5조: SQLAlchemy 2.0 및 Alembic을 사용한 비동기 데이터베이스