Ответ
Механизм Depends в FastAPI является реализацией принципа инверсии зависимостей (Dependency Inversion Principle, D) из SOLID.
Этот принцип утверждает, что модули высокого уровня не должны зависеть от модулей низкого уровня. И те, и другие должны зависеть от абстракций.
В FastAPI Depends работает как система внедрения зависимостей (Dependency Injection). Это позволяет:
- Декларировать зависимости прямо в сигнатуре функции-обработчика.
- Отделить бизнес-логику эндпоинта от логики получения зависимостей (например, сессии БД, аутентификации пользователя).
- Упростить тестирование, так как зависимости можно легко подменить (mock).
Пример:
from fastapi import Depends, FastAPI
app = FastAPI()
# Абстракция: функция, предоставляющая зависимость (например, сессию БД)
def get_db_session():
db_session = "fake_db_session"
try:
yield db_session
finally:
print("DB session closed")
# Модуль высокого уровня (эндпоинт)
@app.get("/items/")
async def read_items(db = Depends(get_db_session)):
# Эндпоинт не создает сессию сам, а получает ее через Depends.
# Он зависит от абстракции `get_db_session`, а не от конкретной реализации.
return {"message": f"Items read from {db}"} Ответ 18+ 🔞
А, ну это же про тот самый принцип, который все всуе поминают, а на деле нихуя не понимают! Слушай сюда, сейчас разжую.
Вот есть у тебя, допустим, роутер, который должен с базой данных работать. По-простому, по-деревенски, ты бы прямо в нём и создавал подключение, да? Ну типа db = connect_to_db(). И вроде бы всё работает, но потом оказывается, что ты, блядь, прирос к этой конкретной базе как репейник к штанам. Захотел протестировать — хуй тебе, а не тесты, потому что везде эта конкретная база зашита. Это и есть нарушение принципа инверсии зависимостей, ёпта!
А суть-то в чём? Модули высокого уровня (твой роутер, твоя бизнес-логика) не должны зависеть от модулей низкого уровня (конкретная функция подключения к PostgreSQL). Они должны зависеть от абстракций! То есть твой роутер должен говорить: «Дайте мне какую-нибудь штуку, через которую я могу с базой общаться», а не «Дайте мне именно эту сессию от этого драйвера».
И вот тут FastAPI подъезжает на белом коне с механизмом Depends. Это, по сути, система внедрения зависимостей, которая делает тебя нереально крутым архитектором, даже если ты вчера только из деревни приехал.
Что она позволяет, блядь?
- Объявлять зависимости прямо в аргументах хэндлера. Красиво, наглядно, сразу видно, что этому эндпоинту нужно для работы.
- Отделить всю эту техническую муть вроде открытия сессий, проверки токенов и прочей ерунды от самой сути — твоей бизнес-логики. Эндпоинт занимается своим делом, а не возится с низкоуровневым хозяйством.
- Тестировать всё это безболезненно. Захотел — подсунул в тестах заглушку вместо реальной базы, и поехали. Никаких костылей, всё элегантно, как у настоящих джентльменов.
Смотри, как это выглядит в коде, тут всё просто, как три копейки:
from fastapi import Depends, FastAPI
app = FastAPI()
# Вот это наша абстракция, наша «фабрика зависимости».
# Она не делает ничего умного, просто говорит: «Эй, кто бы меня ни вызвал, вот тебе сессия!»
def get_db_session():
db_session = "fake_db_session" # Тут, понятное дело, будет реальное подключение
try:
yield db_session # Отдаём сессию тому, кто попросил
finally:
print("DB session closed") # И гарантированно прибираем за собой, даже если всё пошло по пизде
# А вот это наш модуль высокого уровня — эндпоинт.
# Он не парится, КАК получить сессию. Он просто говорит: «Мне нужна сессия».
# А система сама её подсунет через `Depends`.
@app.get("/items/")
async def read_items(db = Depends(get_db_session)):
# И вот он, красавец, работает с базой, даже не зная, откуда она взялась.
return {"message": f"Items read from {db}"}
Вот и вся магия, ёбана! Твой код становится чище, гибче и перестаёт быть монолитной глыбой, которую страшно трогать. А главное — ты начинаешь чувствовать себя не просто кодёром, а архитектором, блядь! Ну, почти.