Ответ
DTO — это шаблон проектирования, представляющий собой простой объект, используемый для передачи данных между подсистемами приложения (слоями, сервисами) с целью снижения связности.
Основные сценарии применения:
-
Изоляция модели предметной области (Domain Model) от слоя представления (API):
- Сокрытие внутренней структуры: Не экспонировать поля JPA-сущности (например,
@OneToManyсвязи, служебные поляversion). - Защита данных: Исключить чувствительные поля (пароли, токены) из ответа API.
- Адаптация формата: Изменить структуру данных под нужды конкретного клиента (UI, мобильное приложение).
- Сокрытие внутренней структуры: Не экспонировать поля JPA-сущности (например,
-
Оптимизация сетевых вызовов (N+1 проблема):
- Объединение данных из нескольких сущностей в один объект для передачи за один запрос, вместо множества последовательных.
-
Работа с удаленными интерфейсами (Web API, RPC):
- Сериализация и десериализация в JSON/XML. DTO часто имеют плоскую структуру, удобную для передачи по сети.
Пример: Отделение Entity от DTO для REST API
// Entity (JPA) — внутренняя модель данных БД
@Entity
public class User {
@Id
private Long id;
private String username;
private String passwordHash; // Конфиденциальное поле!
@OneToMany(mappedBy = "user")
private List<Order> orders; // Детали, не всегда нужные клиенту
// ... геттеры, сеттеры
}
// DTO для ответа API — содержит только необходимые клиенту данные
public class UserProfileDto {
private Long id;
private String username;
// Поля passwordHash и orders отсутствуют
private int orderCount; // Вычисляемое поле для клиента
// Конструктор на основе Entity (маппинг)
public UserProfileDto(User user) {
this.id = user.getId();
this.username = user.getUsername();
this.orderCount = user.getOrders().size();
}
// ... геттеры
}
Использование DTO делает контракт API стабильным и независимым от изменений в модели данных или бизнес-логике.