Подтвердить что ты не робот

Что такое хорошая стратегия для преобразования объектов jpa в резервные ресурсы

У остальных ресурсов не всегда есть сопоставление "один к одному" с вашими объектами jpa. Как я вижу, есть несколько проблем, которые я пытаюсь выяснить, как обращаться:

  • Когда ресурс имеет информацию, которая заполняется и сохраняется несколькими объектами.
  • Когда объект имеет больше информации в нем, которую вы хотите отправить в качестве ресурса. Я мог бы просто использовать Jackson @JsonIgnore, но у меня все равно были бы проблемы с 1, 3 и 4.
  • Когда объект (например, совокупный корень) имеет вложенные объекты и вы хотите включить часть своих вложенных объектов, но только к определенному уровню вложенности в качестве вашего ресурса.
  • Если вы хотите исключить один кусок объекта, когда его часть одного родительского объекта, но исключает отдельную часть, когда ее часть другого родительского объекта.
  • Взорванные циклические ссылки (я получил это в основном с JSOG с помощью Jackson @JsonIdentityInfo)

Возможные решения: Единственный способ, с помощью которого я мог бы подумать, будет справляться со всеми этими проблемами, - это создать целую кучу классов ресурсов, которые имели бы конструкторы, которые занимали бы необходимые объекты для создания ресурса и размещали на нем необходимые геттеры и сеттеры для этого ресурса, Это перебор?

Чтобы решить 2, 3, 4 и 5, я мог бы просто выполнить предварительную и пост-обработку на фактическом объекте перед отправкой его в Jackson для сериализации или десериализации моего pojo в JSON, но это не касается проблемы 1.

Это все проблемы, которые я бы подумал, что другие столкнулись бы, и мне любопытно, какие решения могут предложить другие люди. (В настоящее время я использую JPA 2, Spring MVC, Jackson и Spring -Data, но открыт для других технологий)

4b9b3361

Ответ 1

С помощью комбинации JAX_RS 1.1 и Jackson/GSON вы можете напрямую представлять объекты JPA в качестве ресурсов REST, но вы столкнетесь с множеством проблем.

DTO, то есть проекции на объекты JPA - это путь. Это позволит вам отделить проблемы представления ресурсов от REST от транзакционных проблем JPA. Вы четко определяете характер представлений. Вы можете контролировать объем данных, отображаемых в представлении, включая глубину пройденного графика объекта, если вы тщательно разработаете свои DTO/прогнозы. Возможно, вам понадобится создать несколько DTO/проекций для одного и того же объекта JPA для разных ресурсов, в которых объект может быть представлен по-разному.

Кроме того, в моем опыте использование аннотаций типа @JsonIgnore и @JsonIdentityInfo для объектов JPA точно не предоставляет более удобные представления ресурсов. Вы можете столкнуться с трудностями при объединении объектов обратно в контекст персистентности (из-за игнорируемых свойств), или ваши клиенты могут не иметь возможности потреблять представления ресурсов, поскольку ссылки на объекты как схемы могут быть не поняты. У большинства клиентов JavaScript обычно возникают проблемы с использованием ссылок на объекты, созданных аннотацией @JsonIdentityInfo, из-за отсутствия здесь стандартизации.

Существуют и другие дополнительные аспекты, которые были бы возможны с помощью DTOs/projections. JPA @EmbeddedId не вписываются естественным образом в представления ресурсов REST. Некоторые защитники используют аннотацию JAX-RS @MatrixParam для уникального определения ресурса в URI ресурсов, но это не работает для большинства клиентов. Матричные параметры - это, в конце концов, только примечание к дизайну, а не стандарт (пока). С DTO/проекцией вы можете отображать представление ресурса по вычисленному идентификатору (может быть комбинация составляющих ключей).

Примечание. В настоящее время я работаю над плагином JBoss Forge для REST, где существуют некоторые или все эти проблемы, и будет исправлена ​​в некоторых будущих выпусках через генерацию DTO.

Ответ 2

Я согласен с другими ответами, что DTO - это путь. Они решают много проблем:

  • Разделение слоев и чистый код. В один прекрасный день вам может потребоваться выставить модель данных с использованием другого формата (например, XML) или интерфейса (например, не на основе веб-сервиса). Сохранение всей конфигурации (например, @JsonIgnore, @JsonidentityInfo) для каждого интерфейса/формата в модели домена сделало бы действительно беспорядочным. DTO разделяют проблемы. Они могут содержать всю конфигурацию, требуемую вашим внешним интерфейсом (веб-службой), без внесения изменений в модель домена, которая может оставаться агрегированной для веб-службы и формата.

  • Безопасность - вы легко контролируете то, что подвергается клиенту, и то, что клиенту разрешено изменять.

  • Производительность - вы легко контролируете, что отправляется клиенту.

  • Проблемы, такие как (круговые) ссылки на объекты, лениво загружаемые коллекции, также решаются явным и сознательным образом при конвертации в DTO.

Ответ 3

Учитывая ваши ограничения, похоже, нет другого решения, кроме Data Transfer Objects - да, это происходит достаточно часто, чтобы люди назвали этот шаблон...

Ответ 4

Если приложение полностью CRUDish, тогда путь к работе определенно Spring Data REST, в котором вам абсолютно не нужны DTO. Если это будет сложнее, вы будете более безопасными с DTO, обеспечивающими уровень приложения. Но не пытайтесь инкапсулировать DTO внутри слоя контроллера. Они относятся к служебному слою, потому что отображение также является частью логики (что вы впустили в приложение и что вы выпустили из него). Таким образом, прикладной уровень остается герметичным. Конечно, в большинстве случаев это может быть сочетание этих двух.