
DTO, schema, model, entity: почему в коде всё называется User
alwaysdeterminated 3 минуты назад DTO, schema, model, entity: почему в коде всё называется User Средний 6 мин 0 Программирование * Python * Проектирование API * Веб-разработка * В бэкенде довольно быстро один User...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
Значимый прорыв формирует отрасль ИИ: alwaysdeterminated 3 минуты назад DTO, schema, model, entity: почему в коде всё называется User Средний 6 мин 0 Программирование * Python * Проектирование API * Веб-разработка * В бэкенде довольно быстро один User начинает работать сразу в нескольких сценариях. Сначала его удобно вернуть из API. Потом этим же классом принимают регистрацию.
Потом его сохраняют в базу. Потом в него докидывают status, created_at, password_hash и пару полей для бизнес-логики:class User(BaseModel): id: str | None = None email: EmailStr | None = None password: str | None = None password_hash: str | None = None status: UserStatus | None = None created_at: datetime | None = NoneС виду удобно: один класс на все случаи. А потом выясняется, что:при регистрации password внезапно необязателен;в ответ API случайно протащился password_hash;id отсутствует там, где без него объект не имеет смысла;изменение таблицы начинает ломать внешний контракт;по типу User уже невозможно понять, какие поля в конкретном месте гарантированы.
Технические детали
Проблема не в названии User, а в том, что одним типом пытаются описать объекты, которые принадлежат разным границам и меняются по разным причинам. Эта статья не про обязательные восемь классов на каждую таблицу. Вопрос проще и важнее: что именно сейчас лежит перед нами — DTO, schema, model или entity?
DTO, schema, model и entity расходятся от одного User. Entity: объект, который остаётся собойВ терминах Domain-Driven Design entity — это объект с идентичностью, которая сохраняется во времени и переживает изменение остальных атрибутов. Пользователь может сменить email или имя, но остаться тем же пользователем.
Поэтому его определяет не набор текущих полей, а идентификатор и правила, по которым меняется состояние:class User: def __init__(self, user_id: int, email: str) -> None: self. _email = email @property def email(self) -> str: return self. _email def change_email(self, new_email: str) -> None: self.
Отраслевые последствия
_email = new_emailЗдесь User — не пакет данных. У него есть идентичность и явно прописанная операция, выражающая допустимое изменение состояния. Но само слово entity при этом перегружено.
Например, в ORM им часто называют объект, отображённый на строку таблицы:class UserEntity(Base): __tablename__ = "users" id: Mapped = mapped_column(primary_key=True) public_id: Mapped = mapped_column(String(26), unique=True) email: Mapped = mapped_column(String(320), unique=True) password_hash: Mapped = mapped_column(String(255)) status: Mapped = mapped_column(String(32)) created_at: Mapped = mapped_column(DateTime(timezone=True))У этого класса другая ответственность: таблица, колонки, ограничения и типы базы. Его меняют из-за миграции или особенностей ORM, а не потому, что в домене появился новый способ изменить email. В маленьком сервисе доменный объект и класс ORM вполне могут совпадать.
Но если слои уже разделены, то имя UserEntity становится двусмысленным: это доменная entity или объект ORM?
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.





