Какие основные паттерны проектирования используются в FastAPI?

Ответ

FastAPI построен на нескольких ключевых паттернах, но два основных — это:

  1. Внедрение зависимостей (Dependency Injection, DI)

    • Назначение: Управление ресурсами (сессии БД, аутентификация) и переиспользование общей логики.
    • Реализация: Через функцию Depends.
    from fastapi import Depends, FastAPI
    
    app = FastAPI()
    
    # Зависимость, которую можно переиспользовать
    async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
        return {"q": q, "skip": skip, "limit": limit}
    
    @app.get("/items/")
    async def read_items(commons: dict = Depends(common_parameters)):
        return commons
  2. Объект передачи данных (Data Transfer Object, DTO)

    • Назначение: Валидация, сериализация и документирование данных запроса и ответа.
    • Реализация: С помощью моделей Pydantic.
    from pydantic import BaseModel
    
    # Модель Pydantic выступает в роли DTO
    class Item(BaseModel):
        name: str
        price: float
        is_offer: bool | None = None
    
    @app.post("/items/")
    async def create_item(item: Item):
        # FastAPI автоматически валидирует тело запроса по схеме Item
        return item

Сочетание этих двух паттернов обеспечивает высокую производительность, надежность и удобство разработки в FastAPI.

Ответ 18+ 🔞

Слушай, а давай разберём, на каких двух китах этот ваш FastAPI держится, а то некоторые думают, что там магия какая-то, блядь. А там всё просто, как три копейки, но охуенно продумано.

Первый кит — это Внедрение зависимостей, или, по-пацански, Depends. Ну, сука, представь: тебе на каждом втором эндпоинте нужна сессия к базе или проверка, кто там такой умный пришёл. И что, каждый раз один и тот же код копипастить? Да ну нахуй, это же пиздец какой-то. Вот для этого и Depends. Кидаешь туда функцию, которая тебе что-то готовит — и всё, она становится как бы общим ингредиентом. FastAPI сам её вызовет и результат тебе подсунет. Красота, блядь.

from fastapi import Depends, FastAPI

app = FastAPI()

# Вот эта функция — наша палочка-выручалочка. Общая логика, епта.
async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}

@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)): # Смотри сюда! Подключили зависимость.
    return commons

Второй кит — это Объект передачи данных, он же Pydantic-модель. А вот это, блядь, вообще шедевр. Раньше ты получал данные из запроса, а потом вручную, сука, проверял: а есть ли поле, а того ли оно типа, а не хуйню ли мне прислали? Пиздец, скука смертная. Теперь ты просто описываешь, как должна выглядеть твоя структура, как будто чертёж рисуешь. А FastAPI берёт эту модель, смотрит на входящие данные и говорит: «О, дружок, тут у тебя цена строкой пришла, а в чертеже число. Иди нахуй, исправляй». И всё это автоматически, блядь! И документация сама генерируется — просто ёперный театр.

from pydantic import BaseModel

# Объявляем, как данные должны выглядеть. Всё, больше ничего не надо.
class Item(BaseModel):
    name: str
    price: float
    is_offer: bool | None = None

@app.post("/items/")
async def create_item(item: Item): # FastAPI сам всё проверит и распакует сюда готовый объект.
    return item

Вот и вся магия, ёпта. Depends — чтобы не повторяться и управлять ресурсами умно. Pydantic — чтобы не ебаться с валидацией и чтобы всё было по контракту. Вместе они дают такую скорость и надёжность, что иногда сам от себя охуеваешь.