Обновить

Комментарии 31

Зачем вы минусуете статью? В рассуждениях автора есть изъяны? Можно пояснительную бригаду? Уровень компетенций не позволяет оценить самостоятельно. Спасибо.

Не силен в питоне, но выглядит здраво.

Я не силен в питоне?(

Скорее всего автор коммента не силен

Думаю, автор коммента писал про себя. "[Я] не силен в питоне, но выглядит здраво" Вы поспешили применить оценку к себе.

Почему такой низкий рейтинг ? Понятно, что для многих это базовые вещи, но блин, для новичков самое то, примеры понятные для понимания.

  1. На указанном примере непонятно от чего отделяли бизнес логику. Я полностью поддерживаю идею сервисного слоя, но в указанном примере тема не раскрыта. Что бл отделить, её надо отделять от чего-то. Тут просто не показано от чего. Ещё и возврат словарика из вьюхи - сомнительно, как и возврат доменной модели из сервисного слоя. В общем тема не раскрыта

  2. Использование Depends != Использование Dependency injection. По факту в указанном коде нет dependency injection, есть странный вызов функций с помощью помещения их в сигнатуру вместо обычного вызова. Depends удобен для другого - разделения логики парсинга запроса на части. Да, Рамирез тоже ошибается

  3. Использование pydantic в домене обсуждаемо. Я лично против. Но вот использование pydantic первый версии в статье 2026 года попахивает нейрослопом

Используйте dishka. Ибо вызов таски это тоже своего рода эндпоинт, но в таск менеджерах нет di контейнеров, отсюда и.

Использовать pydantic в домене это фатальная ошибка! Прям я бы сказал ошибка джуна.

Почему?

Проверка типов данных, валидация значений - это все задача адаптеров. Когда мы получили запрос, мы проверили, валидный ли json, типы полей и т.д. тут pydantic хорошо помогает.

На доменном уровне мы работаем с моделями бизнеса. Мы не валидируем с технической точки зрения.

К тому же доменный уровень надо держать максимально чистым от зависимостей и не должен зависеть от транспорта или инструментов валидация например.

Валидация значений вполне себе задача бизнес логики. Тут вам и паттерн ValueObject и методы изменения с проверками инвариантов. Только для этого пидантик не нужен, тем более что он ещё внедряет свои неявные преобразования алиасов и типов.

Доменный уровень действительно не должен зависеть от транспорта, но никто не запрещает использовать там вспомогательные инутрменты, если они достаточно надежные и стабильные. Проблема тут в том, что pydatic модели очень хочется сразу настроить на транспорт, потому что они это могут и будет очень сложно отговаривать коллег каждый раз.

А как вы на форме регистрации нарисуете ошибку для поля емейл, что такой адрес уже существует? Мало того, в самой бизнес логики эту проверку всё равно делать нужно. Пидантик может быть и правда имеет смысл использовать в адаптерах, но вообще то валидация должна быть во всех слоях

Валидация имеет несколько форм. Во-первых валидация по форме. Данные некорректных типов просто не должны попадать в бизнес логику. Эту часть делают на этапе парсинга запроса, тут хорошо справляется пидантик

Во-вторых это валидация бизнес правил. Часть из них ограничены сущностью, часть связаны с иерархией сущностей, часть включают в себя несколько сущностей задействованных в одной операции, а часть вообще распространяются на всю систему. Эти правила силами пидантика делать часто просто невозможно.

Плохая часть пидантика заключается в том, что он смешивает валидацию и парсинг. Это нормально для DTO и первого варианта валидаций, но может иногда стрелять при попытке использования в БЛ.

К тому же домен хочется быть стабильным. Пидантик второй версии ещё слишком молод чтобы претендовать на это

Ну например потому-что доменный слой должен быть изолирован от инфраструктурных деталей. Зависимость от pydantic означает, что бизнес-правила твоего приложения привязаны к библиотеке для парсинга/валидации данных. Да, конечно все эти правила не в камне высечены, но конкретно с этим вроде как в индустрии в целом все согласны и тут давно нет холиваров.

Но если этого недостаточно то вот еще несколько причин:

  1. Примеры в статье достаточно "плюшевые", в нормальном продакшн решении обычно не получается обойтись без конструкторов класса и других dunder-методов, которые модали pydantic при их стандартном использовании не предоставляют, дальше придется городить костыли.

  2. Сами по себе pydantic модели по умолчанию иммутабельные. Доменные модели же обычно требуют изменения состояния с сохранением инвариантов.

  3. Нет адекватной поддержки приватных атрибутов, ты всегда можешь обратиться к любому из своих полей напрямую, минуя API модели. Pydantic имеет PrivateAttr, но это не полноценная инкапсуляция. Доменная модель должна скрывать внутреннее состояние и предоставлять только безопасные методы для его изменения. Да, конечно в python приватность условная, но все же пользователям модели (тут имею в виду других разработчиков, которые не должны лезть внутрь модели чтобы использовать ее) должен быть предоставлен понятный API для взаимодействия с моделью, никакое поле не изменяется напрямую, а только через так называемые геттеры и сеттеры, которые содержат в себе различные правила взаимодействия.

  4. Валидации примеряются при создании модели, но не выполняются при изменении атрибутов модели, а значит правила проверок устанавливаемых значений все равно нужно будет реализовывать в сеттерах. Это обесценивает применение pydantic в доменных моделях.

Ну и в целом ценность доменной модели в том, что на всех этапах своего жизненного цикла в бизнес процессе она имеет полностью ваидные значения. Используя API модели (герреты, сеттеры, и др методы) разработчик может управлять ее состоянием, но при этом он никогда не сможет задать ей не валидное состояние (состояние когда значения атрибутов противоречат бизнес логике), а pydantic никак с этим не помогает.

Для этой задачи хорошо подходит обычный класс с конструктором, приватными атрибутами и понятными методами взаимодействия с этими атрибутами.

В целом, если забить на правило что домен не должен ни от чего зависеть, то pydantic может подойти для реализации объектов-значений, но с этим также хорошо справляются и обычные датаклассы при этом не накладывают никакого оверхеда на производительность.

P.S.
Хочу заметить, что в целом для твоего возраста (если данные в профиле верные) и как следвтсвие опыта это хорошая стаья, несмотря на критику) Не сдавайся))

спасибо за критику. Сейчас работаю в одиночку над проектом для огромной организации, получается придется чистить домены от pydantic моделей и переходить на dataclass, ибо у меня там одно месево из моделей.

Там есть второе опасное место - дублирование ORM моделей и моделей бл. Если вы так делаете, у вас будут проблемы с idm и UoW алхимии.

Когда тыкал на заголовок, ожидал разбор архитектуры самого FastAPI, если честно. Ну а статья… Непонятно, для кого она написана, если всё это можно узнать у чатгпт одним небольшим промптом. Может, лучше статью «5 промптов, которые я пожалел что не отправил чатгпт раньше»?

Неприятно чувствую себя, когда понимаю что в мой коммент примерно столько же сил вложено сколько и в разработку статьи (поправьте меня если это не нейроген)

не нейроген. Статья предназначена для новичков, да и генерить тут нечего, Писать 5 минут

1) Почему сервисный слой знает статус коды HTTP слоя?

2) Использование Pydantic моделей в домене как по мне плохая идея. Лучше датаклассы с мапером.

3) Почему синхронный rq, а не как минимум arq?

1) почему бы и нет? Ничего критического от этого не будет, но да, я согласен что так делать лучше не надо
2) каждый пишет код по разному, я лично привык использовать pydantic модели.
3) в статье я не говорю что нужно писать прям как на примере и использовать такие же библиотеки, я показываю архитектурные приемы и вы конечно можете использовать arq

1) Потому что в мире есть что-то кроме HTTP, тот же gRPC, CLI и тд. Это нарушение архитектуры. Сервисный слой не должен быть привязан к транспорту.

2) Писать нужно правильно, а не как хочется, если вы хотите писать хороший, расширяемый код. Pydantic создан для валидации, а не для БЛ. Доменные модели не должны зависеть от сторонних библиотек и сам факт использования для нмх Pydantic вызывает много проблем.

3) Выбор библиотек это часть архитектурных решений. Почему нельзя показать сразу правильный подход? RQ в async проекте это как "заряжать теслу от бензинового генератора".

Какие проблемы вызовет использование пидантика для доменных моделей?

Ну, кстати, да. Для новичков релевантнее было бы написать статью именно по архитектуре FastAPI. Для первых шагов.Как бы, намёк :)

Стоит писать статью про то как работает FastAPI под капотом?

Я не уверен. Там каша и большую часть делает все равно starlette.

Я как человек недавно написавший на fastapi 5000 строк пет-проекта (родной С++), могу сказать что идея классная. Но ребята верно пишут, загонять бизнес классы под pydantic выглядит не очень, http коды в сервисе тоже не очень, но идея хорошая, и это уже про этап рефакторинга зрелого проекта, на старте, лучше так не делать, т.к. уйдете в красоту кода, а не бизнес задачи.

Не помещайте в pydantic модели лишнюю логику. Поимеете кучу проблем потом с толстыми моделями. Даже бизнес валидации не суйте в них. Эти модели чисто для валидаций простых типов и чтоб в словарь/ json потом сконвертить.

Статья полезна тем, что из критики в комментариях узнаешь гораздо больше чем из статьи ).

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации