← Назад к вопросам

Какой паттерн есть в FastAPI, который отличиает его от других фреймворков?

2.0 Middle🔥 191 комментариев
#FastAPI и Flask#REST API и HTTP

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Dependency Injection в FastAPI

Одной из самых отличительных и мощных особенностей FastAPI является встроенная система Dependency Injection (DI). Это паттерн, который выделяет FastAPI среди других Python веб-фреймворков (Flask, Django) своей элегантностью и интеграцией.

Суть паттерна

Dependency Injection позволяет описывать зависимости в функциях-обработчиках, и FastAPI автоматически:

  • Разрешает эти зависимости
  • Кэширует их в рамках одного запроса
  • Внедряет в функцию
  • Валидирует и сериализует данные

Базовый пример

from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session

app = FastAPI()

def get_db():
    # Получаем сессию БД
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/users/{user_id}")
def get_user(user_id: int, db: Session = Depends(get_db)):
    # FastAPI автоматически вызовет get_db() и подставит результат
    user = db.query(User).filter(User.id == user_id).first()
    return user

Преимущества перед другими фреймворками

1. Встроенная поддержка — не нужны сторонние библиотеки вроде dependency-injector или inject.

2. Интеграция с типизацией — FastAPI использует type hints для автоматической валидации:

from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int

def validate_user(user: User = Depends()):
    # FastAPI автоматически валидирует данные из JSON body
    return user

@app.post("/users")
def create_user(user: User = Depends(validate_user)):
    return user

3. Кэширование на уровне запроса:

def get_current_user(token: str = Header()):
    user = parse_token(token)  # Вычисляется один раз
    return user

@app.get("/profile")
def get_profile(user = Depends(get_current_user)):
    return {"profile": user}

@app.get("/posts")
def get_user_posts(user = Depends(get_current_user)):
    # user получит ТОТ ЖЕ объект из кэша, не перевычисляется
    return [p for p in posts if p.user_id == user.id]

4. Композиция зависимостей — вложенные зависимости работают интуитивно:

def get_current_user(token: str = Header()) -> User:
    return parse_token(token)

def get_admin_user(user: User = Depends(get_current_user)) -> User:
    if user.role != "admin":
        raise HTTPException(status_code=403)
    return user

@app.delete("/users/{user_id}")
def delete_user(user_id: int, admin = Depends(get_admin_user)):
    # Гарантированно передается только администратор
    db.delete_user(user_id)

Отличие от Flask/Django

Flask требует использовать декораторы и контекстные менеджеры для зависимостей:

# Flask - нужны сторонние библиотеки
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)

Django имеет встроенные зависимости через settings и middleware, но это менее гибко:

# Django - жестко привязано к settings и ORM
from django.db import connection

FastAPI - всё в одном месте и типизировано:

# FastAPI - явно, типизировано, переиспользуемо
def get_db() -> Generator[Session, None, None]:
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

Сложные сценарии

Условные зависимости:

async def verify_token(request: Request):
    token = request.headers.get("Authorization")
    if not token:
        return None
    return parse_token(token)

@app.get("/data")
async def get_data(user = Depends(verify_token)):
    if user is None:
        return {"public": "data"}
    return {"private": "data", "user": user.name}

Итог

Dependency Injection в FastAPI - это не просто удобство, это фундамент архитектуры. Он делает код более тестируемым, модульным и безопасным. Это главное отличие FastAPI от конкурентов на Python.

Какой паттерн есть в FastAPI, который отличиает его от других фреймворков? | PrepBro