Comments 30
Зачем вы минусуете статью? В рассуждениях автора есть изъяны? Можно пояснительную бригаду? Уровень компетенций не позволяет оценить самостоятельно. Спасибо.
Не силен в питоне, но выглядит здраво.
Почему такой низкий рейтинг ? Понятно, что для многих это базовые вещи, но блин, для новичков самое то, примеры понятные для понимания.
На указанном примере непонятно от чего отделяли бизнес логику. Я полностью поддерживаю идею сервисного слоя, но в указанном примере тема не раскрыта. Что бл отделить, её надо отделять от чего-то. Тут просто не показано от чего. Ещё и возврат словарика из вьюхи - сомнительно, как и возврат доменной модели из сервисного слоя. В общем тема не раскрыта
Использование Depends != Использование Dependency injection. По факту в указанном коде нет dependency injection, есть странный вызов функций с помощью помещения их в сигнатуру вместо обычного вызова. Depends удобен для другого - разделения логики парсинга запроса на части. Да, Рамирез тоже ошибается
Использование pydantic в домене обсуждаемо. Я лично против. Но вот использование pydantic первый версии в статье 2026 года попахивает нейрослопом
Используйте dishka. Ибо вызов таски это тоже своего рода эндпоинт, но в таск менеджерах нет di контейнеров, отсюда и.
Использовать pydantic в домене это фатальная ошибка! Прям я бы сказал ошибка джуна.
Почему?
Проверка типов данных, валидация значений - это все задача адаптеров. Когда мы получили запрос, мы проверили, валидный ли json, типы полей и т.д. тут pydantic хорошо помогает.
На доменном уровне мы работаем с моделями бизнеса. Мы не валидируем с технической точки зрения.
К тому же доменный уровень надо держать максимально чистым от зависимостей и не должен зависеть от транспорта или инструментов валидация например.
Валидация значений вполне себе задача бизнес логики. Тут вам и паттерн ValueObject и методы изменения с проверками инвариантов. Только для этого пидантик не нужен, тем более что он ещё внедряет свои неявные преобразования алиасов и типов.
Доменный уровень действительно не должен зависеть от транспорта, но никто не запрещает использовать там вспомогательные инутрменты, если они достаточно надежные и стабильные. Проблема тут в том, что pydatic модели очень хочется сразу настроить на транспорт, потому что они это могут и будет очень сложно отговаривать коллег каждый раз.
А как вы на форме регистрации нарисуете ошибку для поля емейл, что такой адрес уже существует? Мало того, в самой бизнес логики эту проверку всё равно делать нужно. Пидантик может быть и правда имеет смысл использовать в адаптерах, но вообще то валидация должна быть во всех слоях
Валидация имеет несколько форм. Во-первых валидация по форме. Данные некорректных типов просто не должны попадать в бизнес логику. Эту часть делают на этапе парсинга запроса, тут хорошо справляется пидантик
Во-вторых это валидация бизнес правил. Часть из них ограничены сущностью, часть связаны с иерархией сущностей, часть включают в себя несколько сущностей задействованных в одной операции, а часть вообще распространяются на всю систему. Эти правила силами пидантика делать часто просто невозможно.
Плохая часть пидантика заключается в том, что он смешивает валидацию и парсинг. Это нормально для DTO и первого варианта валидаций, но может иногда стрелять при попытке использования в БЛ.
К тому же домен хочется быть стабильным. Пидантик второй версии ещё слишком молод чтобы претендовать на это
Ну например потому-что доменный слой должен быть изолирован от инфраструктурных деталей. Зависимость от pydantic означает, что бизнес-правила твоего приложения привязаны к библиотеке для парсинга/валидации данных. Да, конечно все эти правила не в камне высечены, но конкретно с этим вроде как в индустрии в целом все согласны и тут давно нет холиваров.
Но если этого недостаточно то вот еще несколько причин:
Примеры в статье достаточно "плюшевые", в нормальном продакшн решении обычно не получается обойтись без конструкторов класса и других dunder-методов, которые модали pydantic при их стандартном использовании не предоставляют, дальше придется городить костыли.
Сами по себе pydantic модели по умолчанию иммутабельные. Доменные модели же обычно требуют изменения состояния с сохранением инвариантов.
Нет адекватной поддержки приватных атрибутов, ты всегда можешь обратиться к любому из своих полей напрямую, минуя API модели. Pydantic имеет PrivateAttr, но это не полноценная инкапсуляция. Доменная модель должна скрывать внутреннее состояние и предоставлять только безопасные методы для его изменения. Да, конечно в python приватность условная, но все же пользователям модели (тут имею в виду других разработчиков, которые не должны лезть внутрь модели чтобы использовать ее) должен быть предоставлен понятный API для взаимодействия с моделью, никакое поле не изменяется напрямую, а только через так называемые геттеры и сеттеры, которые содержат в себе различные правила взаимодействия.
Валидации примеряются при создании модели, но не выполняются при изменении атрибутов модели, а значит правила проверок устанавливаемых значений все равно нужно будет реализовывать в сеттерах. Это обесценивает применение pydantic в доменных моделях.
Ну и в целом ценность доменной модели в том, что на всех этапах своего жизненного цикла в бизнес процессе она имеет полностью ваидные значения. Используя API модели (герреты, сеттеры, и др методы) разработчик может управлять ее состоянием, но при этом он никогда не сможет задать ей не валидное состояние (состояние когда значения атрибутов противоречат бизнес логике), а pydantic никак с этим не помогает.
Для этой задачи хорошо подходит обычный класс с конструктором, приватными атрибутами и понятными методами взаимодействия с этими атрибутами.
В целом, если забить на правило что домен не должен ни от чего зависеть, то pydantic может подойти для реализации объектов-значений, но с этим также хорошо справляются и обычные датаклассы при этом не накладывают никакого оверхеда на производительность.
P.S.
Хочу заметить, что в целом для твоего возраста (если данные в профиле верные) и как следвтсвие опыта это хорошая стаья, несмотря на критику) Не сдавайся))
спасибо за критику. Сейчас работаю в одиночку над проектом для огромной организации, получается придется чистить домены от pydantic моделей и переходить на dataclass, ибо у меня там одно месево из моделей.
Когда тыкал на заголовок, ожидал разбор архитектуры самого FastAPI, если честно. Ну а статья… Непонятно, для кого она написана, если всё это можно узнать у чатгпт одним небольшим промптом. Может, лучше статью «5 промптов, которые я пожалел что не отправил чатгпт раньше»?
1) Почему сервисный слой знает статус коды HTTP слоя?
2) Использование Pydantic моделей в домене как по мне плохая идея. Лучше датаклассы с мапером.
3) Почему синхронный rq, а не как минимум arq?
1) почему бы и нет? Ничего критического от этого не будет, но да, я согласен что так делать лучше не надо
2) каждый пишет код по разному, я лично привык использовать pydantic модели.
3) в статье я не говорю что нужно писать прям как на примере и использовать такие же библиотеки, я показываю архитектурные приемы и вы конечно можете использовать arq
1) Потому что в мире есть что-то кроме HTTP, тот же gRPC, CLI и тд. Это нарушение архитектуры. Сервисный слой не должен быть привязан к транспорту.
2) Писать нужно правильно, а не как хочется, если вы хотите писать хороший, расширяемый код. Pydantic создан для валидации, а не для БЛ. Доменные модели не должны зависеть от сторонних библиотек и сам факт использования для нмх Pydantic вызывает много проблем.
3) Выбор библиотек это часть архитектурных решений. Почему нельзя показать сразу правильный подход? RQ в async проекте это как "заряжать теслу от бензинового генератора".
Ну, кстати, да. Для новичков релевантнее было бы написать статью именно по архитектуре FastAPI. Для первых шагов.Как бы, намёк :)
как насчет этой? https://habr.com/ru/companies/pt/articles/820171
Я как человек недавно написавший на fastapi 5000 строк пет-проекта (родной С++), могу сказать что идея классная. Но ребята верно пишут, загонять бизнес классы под pydantic выглядит не очень, http коды в сервисе тоже не очень, но идея хорошая, и это уже про этап рефакторинга зрелого проекта, на старте, лучше так не делать, т.к. уйдете в красоту кода, а не бизнес задачи.
Не помещайте в pydantic модели лишнюю логику. Поимеете кучу проблем потом с толстыми моделями. Даже бизнес валидации не суйте в них. Эти модели чисто для валидаций простых типов и чтоб в словарь/ json потом сконвертить.
Статья полезна тем, что из критики в комментариях узнаешь гораздо больше чем из статьи ).
FastAPI: 5 практичных архитектурных решений, о которых я пожалел, что не узнал раньше