it-swarm.com.ru

REST API - DTO или нет?

В настоящее время я создаю REST-API для проекта и читаю статью за статьей о лучших практиках. Многие, кажется, против DTO и просто выставляют модель предметной области, в то время как другие, кажется, думают, что DTO (или пользовательские модели, или как вы хотите это называть) - плохая практика. Лично я думал, что эта статья имеет большой смысл.

Однако я также понимаю недостатки DTO со всем дополнительным кодом отображения, модели доменов, которые могут быть на 100% идентичны их DTO-аналогам, и так далее.

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

Дело в том, что мы можем не захотеть предоставлять все данные домена другим пользователям клиента. Большая часть данных будет иметь смысл только в нашем собственном веб-приложении. Кроме того, мы можем не захотеть раскрывать все данные об объекте во всех сценариях, особенно об отношениях с другими объектами и так далее. Например, если мы представляем список определенного объекта, мы не обязательно хотим раскрывать всю иерархию объектов; так что дочерние объекты не будут выставлены, но могут быть обнаружены через ссылки (hateoas).

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

113
benbjo

Почему вы должны использовать DTO в своем REST API

DTO означает D ata T перевод O bject .

Этот шаблон был создан с очень четко определенной целью: передавать данные на удаленные интерфейсы , как веб-сервисы . Этот шаблон очень хорошо вписывается в API REST, и DTO дадут вам большую гибкость в долгосрочной перспективе.

Представления ресурсов REST не обязательно должны иметь те же атрибуты, что и модели персистентности: вам может потребоваться опустить, добавить или переименовать атрибуты.

Просто упомяну несколько преимуществ использования DTO вместо моделей персистентности:

  • Отделите ваши модели персистентности от ваших моделей API.

  • DTO могут быть адаптированы к вашим потребностям, и они хороши, когда вы выставляете только набор атрибутов ваших постоянных сущностей. Вам не понадобятся аннотации, такие как @XmlTransient и @JsonIgnore , чтобы избежать сериализации некоторых атрибутов.

  • Используя DTO, вы избежите адских аннотаций в ваших персистентных сущностях, то есть ваши персистентные сущности не будут раздуты аннотациями, не связанными с персистентностью.

  • Вы будете иметь полный контроль над атрибутами, которые вы получаете при создании или обновлении ресурса.

  • Если вы используете Swagger , вы можете использовать @ApiModel и @ApiModelProperty аннотации для документирования ваших моделей API без путаницы в ваших персистентных сущностях.

  • Вы можете иметь разные DTO для каждой версии вашего API.

  • Вы будете иметь больше гибкости при отображении отношений.

  • Вы можете иметь разные DTO для разных типов медиа.

  • Ваши DTO могут иметь список ссылок для HATEOAS . Такого рода вещи не следует добавлять к объектам персистентности.

Работа с шаблоном кода

Вам не нужно будет привязывать ваши персистентные сущности к DTO и наоборот вручную . Есть много картографических фреймворков , которые вы можете использовать для этого. Например, взгляните на MapStruct , который основан на аннотациях и работает как обработчик аннотаций Maven. Он хорошо работает как в CDI, так и в Spring-приложениях.

Вы также можете рассмотреть Lombok для генерации методов получения, установки, equals(), hashcode() и toString().


Связанный: Чтобы дать лучшие имена вашим классам DTO, обратитесь к этому ответ .

186
cassiomolin

Когда ваш API общедоступен, и вы должны поддерживать несколько версий, вы должны использовать DTO.

С другой стороны, если это частный API и вы управляете клиентом и сервером, я склонен пропускать DTO и выставлять модель домена напрямую.

18
David Siro

Я склонен использовать DTO.

Мне не нравятся недостатки, но кажется, что другие варианты еще хуже:

Экспозиция объектов домена может привести к проблемам безопасности и утечке данных. Может показаться, что аннотации Джексона решают проблему, но слишком легко ошибиться и раскрыть данные, которые не следует раскрывать. При разработке класса DTO совершить такую ​​ошибку гораздо сложнее.

С другой стороны, недостатки подхода DTO могут быть уменьшены с помощью таких вещей, как сопоставление объектов с объектами и Lombok для меньшего количества шаблонов.

11
Argb32

Как вы уже заявили, это явно вопрос, связанный с мнением. Я сам больше отношусь к подходу без DTO, просто из-за всего необходимого вам кода.

Это в основном верно для ответной стороны json/rest api. Я даже написал аддон Джексона, чтобы избежать написания многих представлений/фильтров json для этих случаев: https://github.com/Antibrumm/jackson-antpathfilter

С другой стороны, DTO - хорошая вещь на стороне ввода данных таких API. Работать напрямую с сущностями может быть довольно сложно, например, принимая во внимание двунаправленные отношения. Также вы действительно не хотите, чтобы вызывающая сторона изменяла атрибут "создатель", например. Таким образом, вам нужно будет запретить определенные поля при отображении таких запросов.

5
Martin Frey