В документации не описаны проблемы передачи сущности с REST DataStore в RestService бэкенда

Репост с англоязычного форума В документации не описаны проблемы передачи сущности с REST DataStore в RestService бэкенда - Ideas - Jmix

В документации для REST DataStore приложения предлагается создавать “дубликаты” сущностей с бэка с аннотациями @JmixEntity, @Store (не обязательно полные) (REST DataStore :: Документация Jmix). Фреймворк хорошо работает с такими “дубликатами”, поддерживается фильтрация, сортировка, экранная валидация, привязка данных и тд.
Также в документации есть примеры использования @RestService, который может принимать на вход такие “дубликаты” (Integrating Jmix Applications :: Документация Jmix). То есть со стороны бэка это выглядит как сервис, который принимает на вход jpa сущность, но на самом деле туда приходит “дубликат” смаппленный в объект jpa сущности.
Это приводит к ряду проблем:

  1. Так как “дубликат” не обязательно полный, то некоторые поля будут просто null. То же самое для полей которые есть в дубликате, но не были загружены. Я не нашел способа как в сервисе можно определить, каких полей нет в дубликате, какие поля не загружены, а какие действительно заданы как null самим пользователем. Отсюда возникает риск ошибочно затереть данные для таких полей в базе. Найти такую ошибку будет не просто, избегать её тоже сложно, для этого нужно будет делать полный дубликат и не забывать синхронизировать его с jpa сущностью бэка при любых изменениях.
    P.S. Даже если был бы способ узнать какие поля загружены а какие нет, то это заставляет сервис знать об устройстве дубликатов на фронте и работать с ними иначе, чем с настоящими jpa сущностями, что не есть хорошо.
    P.P.S. В ТГ чате jmix, предлагали вместе с дубликатом передавать фетч план (Загрузка сущностей :: Документация Jmix), а также попробовать использовать кастомные сервисы обновления (Что нового :: Документация Jmix)).
  2. Иногда бывают обязательные поля, которые не задуманы для заполнения самим пользователем, их должен автоматически заполнить бэк при создании сущности. При работе через сервис, фронту придется самому заботиться о заполнении таких полей, либо в каждом экране просить бэк, чтобы он выдал новую предзаполненную сущность фронту (опять же на фронте должны быть все эти поля, даже если они там не нужны).
  3. Дубликат приходит в сервис в статусе new, даже если это уже существующая сущность, из-за этого её не удается сохранить.

Эти проблемы кажутся логичными, но я не нашел никаких упоминаний о них в документации (только что лишние и не загруженные атрибуты “дубликата” будут null на фронте). Когда сталкиваешься с этими проблемами, то не понятно как поступать “правильно”, как разработчики фреймворка рекомендуют решать эти проблемы, правильно ли вообще передавать “дубликат” в сервис (вроде в документации передают), баги ли это (с одной стороны логично, что сервис не знает о том что загружено, а что нет, с другой стороны через dataManager всё работает нормально), а может сохранение нужно делать только через dataManager, а для своей логики использовать EntityChangedEvent.
Кажется было бы логично сделать DTO и передавать его в сервис, но есть мнение, что использование DTO не соответствует философии jmix, что это усложнит разработку, и что мы потеряем некоторые фичи фреймворка, если пойдем по такому пути. В общем не понятно “одобряет” ли фреймворк работу с DTO в таком случае или какое решение рекомендуется.
Пока что DTO кажется хорошим вариантом, если его использовать не в самих экранах, а просто как промежуточное звено между экраном и сервисом. Это решение также предлагали и в ТГ чате jmix.

Поэтому прошу рассмотреть возможность указания перечисленных проблем в документации (а может их исправления, если это действительно баги), рекомендаций по работе с ними, каково мнение фреймворка по этому поводу, какие варианты “одобрены”, а какие не желательны при работе с jmix.

Добрый день!

Спасибо за сообщение о проблемах. Вы верно описали все сложности, но это не баги.

DataManager действует умнее чем кастомный RestService потому что он сначала перезагружает из БД сущность при ее десериализации. Делать то же самое при передаче параметров произвольному сервису я считаю неправильным.

К сущности-параметру сервиса нужно относится как к DTO, и кастомно обрабатывать его содержимое. Или еще лучше явно передавать не сущность а набор значений или специальный DTO - это не противоречит никаким принципам Jmix, просто придется написать больше кода (который был бы написан в приложении без Jmix).

Добавил в документацию пояснения: REST DataStore :: Jmix Documentation

С уважением,
Константин

1 лайк