День 2318. #ЗаметкиНаПолях
DTO и Маппинг: Хорошее, Плохое, Лишнее. Начало
DTO — это объекты, используемые для передачи данных между различными слоями или уровнями приложения. Они часто используются для сопоставления (маппинга) данных из одного представления в другое, особенно при пересечении границ, например, между БД и слоем UI или API.
Часто возникает путаница вокруг термина «сущность». Некоторые думают о сущностях в контексте ORM, такого как Entity Framework в .NET. В этом случае сущность — это просто сопоставление модели данных с таблицей БД. Другие думают о сущностях в смысле DDD, где это модель с поведением и идентичностью в пределах предметной области.
Зачем добавляют DTO?
Самая распространённая причина - нежелание раскрывать свою базовую модель данных или модель домена. Например, если сущность ORM напрямую отображается в схему БД, вы можете не захотеть отправлять именно эту сущность через API или на другой уровень приложения. Вместо этого вы создаёте DTO (отображение этой сущности), который отправляете дальше. Это справедливо в некоторых контекстах. Но почему просто не возвращать базовую сущность?
Сервисы сущностей и HTTP API: корень некоторых догм DTO
Часто люди создают DTO, почти идентичные своим сущностям. Конечные точки API сопоставляют операции CRUD напрямую с таблицами БД:
- GET – получение заказа,
- POST – создание,
- PUT – обновление,
- PATCH - частичное обновление,
- DELETE – удаление.
При этом API напрямую отображает методы HTTP на CRUD-операции БД. В этом поначалу нет ничего плохого, но это заставляет вас следовать определённым путем. В итоге вы начинаете думать об API просто как о тонком слое поверх схемы БД. Но API не должен быть таким. Ресурсы, предоставляемые API, не должны быть идентичны записям БД. В приложении, где UI создаётся на стороне сервера, вы бы собирали данные из нескольких источников, чтобы создать полноценное HTML-представление, а не брали бы голые данные из одной таблицы.
Например, если вы возвращаете DTO созданного заказа вы бы включили только его ID, дату создания и статус. Но если вы создаёте UI на стороне сервера, вы бы добавили информацию о клиенте (например, имя), которой может не быть непосредственно в объекте заказа. Также вы бы отобразили возможные действия, которые может выполнить пользователь, вроде «Выполнить», «Отменить» или «Отметить оплату».
Когда вы думаете исключительно в терминах сервисов сущностей и записей БД, вы упускаете эту более богатую композицию. В итоге вы получаете DTO, которые являются просто тонкими оболочками вокруг таблиц БД, не сильно отличающимися от самих сущностей.
Реальная ценность DTO
Есть два основных преимущества использования DTO:
1. Управление связанностью.
DTO помогают контролировать, насколько тесно внешние слои или потребители связаны с внутренними моделями данных.
2. Композиция
DTO позволяют составлять данные из нескольких источников или моделей в единую удобную форму, оптимизированную для конкретного варианта использования или потребителя.
Если вы не делаете никакой композиции и ваши DTO почти идентичны записям БД, то вы, скорее всего, делаете лишнюю работу. Каждый раз при смене базовой модели данных, вы вынуждены обновлять несколько DTO на разных уровнях, что добавляет сложности и накладных расходов на обслуживание, не обеспечивая при этом реальной ценности.
Но, если вы хорошо управляете связанностью и контролируете, как отображаются ваши внутренние модели, DTO становятся очень полезными. Они действуют как защитный слой, который позволяет развивать внутренние модели данных, не нарушая внешних потребителей. Если у вас пока нет этой проблемы (у вас немного потребителей, и вы хорошо управляете связями), то создание нескольких DTO «на всякий случай» может оказаться преждевременной оптимизацией.
Окончание следует…
Источник: https://codeopinion.com/dtos-mapping-the-good-the-bad-and-the-excessive/
>>Click here to continue<<