Когда мне следует использовать RequestFactory против GWT-RPC?

87

Я пытаюсь понять, следует ли мне перенести свои вызовы gwt-rpc на новые календари GWT2.1 RequestFactory.

В документации Google смутно упоминается, что RequestFactory - лучший метод связи клиент-сервер для «служб, ориентированных на данные».

Что я могу выделить из документации, так это то, что существует новый класс Proxy, который упрощает взаимодействие (вы не передаете туда и обратно фактический объект, а только прокси, поэтому он легче и проще в управлении)

В этом весь смысл, или я упускаю что-то еще в общей картине?

Даган ---
источник
8
ура, этот вопрос связан с официальным руководством разработчиков gwt !
törzsmókus

Ответы:

73

Большая разница между GWT RPC и RequestFactory заключается в том, что система RPC является «RPC-по-конкретному типу», а RequestFactory - «RPC-по-интерфейсу».

Начать работу с RPC удобнее, поскольку вы пишете меньше строк кода и используете один и тот же класс как на клиенте, так и на сервере. Вы можете создать Personкласс с кучей геттеров и сеттеров и, возможно, с некоторой простой бизнес-логикой для дальнейшего разделения данных в Personобъекте. Это работает достаточно хорошо, пока вы не захотите иметь специфичный для сервера, не-совместимый с GWT код внутри вашего класса. Поскольку система RPC основана на наличии одного и того же конкретного типа как на клиенте, так и на сервере, вы можете столкнуться с проблемой сложности, основанной на возможностях вашего клиента GWT.

Чтобы обойти использование несовместимого кода, многие пользователи создают одноранговый узел, PersonDTOкоторый затеняет реальный Personобъект, используемый на сервере. PersonDTOТолько есть подмножество геттеры и сеттеры серверной стороне, «домен», Personобъект. Теперь вы должны написать код , который Маршалловы данные между блоком Personи PersonDTOобъектом и все другими типами объектов , которые вы хотите передать клиенту.

RequestFactory начинает с предположения, что объекты вашего домена не будут совместимы с GWT. Вы просто объявляете свойства, которые должны быть прочитаны и записаны клиентским кодом в интерфейсе Proxy, а серверные компоненты RequestFactory позаботятся о маршалинге данных и вызове ваших методов службы. Для приложений, которые имеют четко определенную концепцию «Сущностей» или «Объектов с идентификатором и версией», этот EntityProxyтип используется для предоставления клиентскому коду постоянной идентичности семантики ваших данных. Простые объекты отображаются с использованием ValueProxyтипа.

Используя RequestFactory, вы платите авансовую стоимость запуска, чтобы приспособить более сложные системы, чем легко поддерживает GWT RPC. RequestFactory ServiceLayerпредоставляет значительно больше хуков для настройки своего поведения путем добавления ServiceLayerDecoratorэкземпляров.

BobV
источник
Это хороший повод поддержать мое решение перейти на RequestFactory. Спасибо, Боб! Это имеет смысл, и я не понимаю, почему некоторые люди говорят «используйте RPC в некоторых случаях и RF в других, в зависимости от ваших потребностей», потому что кажется, что с RPC вам нужно написать много связующего кода и этого слоя DTO
Дэн Л.
5
Еще один плюс RequestFactory в том, что его можно использовать с Android и GWT с одним и тем же кодом.
Patrick
28

Я прошел переход с RPC на RF. Во-первых, я должен сказать, что мой опыт ограничен в этом, я использовал столько EntityProxies, сколько 0.

Преимущества GWT RPC:

  • Это очень легко настроить, понять и УЧИТЬСЯ!
  • На клиенте и на сервере используются одни и те же объекты на основе классов.
  • Такой подход экономит массу кода.
  • Идеально, когда одни и те же объекты модели (и POJOS) используются на клиенте и сервере, POJOs == MODEL OBJECTs == DTO
  • Легко переносить данные с сервера на клиент.
  • Простая реализация общей логики между клиентом и сервером (это может оказаться серьезным недостатком, когда вам понадобится другая логика).

Недостатки GWT RPC:

  • Невозможно иметь разные реализации некоторых методов для сервера и клиента, например, вам может потребоваться использовать другую структуру ведения журнала на клиенте и сервере или другой метод равенства.
  • ДЕЙСТВИТЕЛЬНО ПЛОХАЯ реализация, которая не подлежит дальнейшему расширению: большая часть функций сервера реализована как статические методы в классе RPC. ЭТО ДЕЙСТВИТЕЛЬНО ОТСТОЙ.
  • например, невозможно добавить обфускацию ошибок на стороне сервера
  • Некоторые проблемы безопасности XSS, которые не совсем элегантно решаются, см. Документацию (я не уверен, что это более элегантно для RequestFactory)

Недостатки RequestFactory:

  • ДЕЙСТВИТЕЛЬНО СЛОЖНО понять из официалки, в чём заслуга! Он начинается прямо с вводящего в заблуждение термина ПРОКСИ - на самом деле это DTO РФ, которые создаются РФ автоматически. Прокси-серверы определяются интерфейсами, например, @ProxyFor (Journal.class). IDE проверяет, существуют ли соответствующие методы в журнале. Вот и все о картографии.
  • RF мало что сделает для вас с точки зрения общности клиента и сервера, потому что
  • На клиенте вам необходимо преобразовать «ПРОКСИ» в объекты клиентского домена и наоборот. Это совершенно нелепо. Это можно сделать декларативно несколькими строчками кода, но ЭТОГО НЕТ ПОДДЕРЖКИ! Если бы только мы могли более элегантно сопоставить наши объекты домена с прокси, что-то вроде метода JavaScript JSON.stringify (.. ,,) ОТСУТСТВУЕТ в панели инструментов RF.
  • Не забывайте, что вы также несете ответственность за установку переносимых свойств объектов вашего домена на прокси и так далее рекурсивно.
  • НЕПРАВИЛЬНАЯ ОБРАБОТКА ОШИБОК на сервере и трассировки стека по умолчанию опускаются на сервере, и вы получаете пустые бесполезные исключения на клиенте. Даже когда я установил собственный обработчик ошибок, я не смог добраться до трассировки стека низкого уровня! Ужасно.
  • Некоторые мелкие ошибки в поддержке IDE и других местах. Я отправил два запроса об ошибке, которые были приняты. Не нужен был Эйнштейн, чтобы понять, что это на самом деле ошибки.
  • ДОКУМЕНТАЦИЯ ОТСТОИТ. Как я уже упоминал, прокси-серверы следует объяснить лучше, термин НЕВЕРОЯТНЫЙ. Для основных распространенных проблем, которые я решал, DOCS БЕСПОЛЕЗНА. Еще один пример непонимания со стороны DOC - подключение аннотаций JPA к RF. Судя по краткой документации, они вроде как играют вместе, и да, есть соответствующий вопрос по StackOverflow. Я рекомендую забыть о любых «соединениях» JPA, прежде чем понимать RF.

Преимущества RequestFactory

  • Отличная поддержка на форуме.
  • Поддержка IDE неплохая (но не является преимуществом по сравнению с RPC)
  • Гибкость реализации вашего клиента и сервера (слабая связь)
  • Необычные вещи, связанные с EntityProxies, помимо простых DTO - кеширование, частичные обновления, очень полезные для мобильных устройств.
  • Вы можете использовать ValueProxies как простейшую замену DTO (но вам придется делать все не очень сложные преобразования самостоятельно).
  • Поддержка Bean Validations JSR-303.

Рассматривая другие недостатки GWT в целом:

  • Невозможно запустить интеграционные тесты (код клиента GWT + удаленный сервер) с предоставленной поддержкой JUnit <= все JSNI должны быть имитированы (например, localStorage), SOP является проблемой.

  • Нет поддержки для настройки тестирования - безголовый браузер + удаленный сервер <= нет простого автономного тестирования для GWT, SOP.

  • Да, можно запускать тесты интеграции селена (но это не то, что я хочу)

  • JSNI очень мощный инструмент, но в блестящих выступлениях на конференциях они не особо много говорят о том, что для написания кодов JSNI есть некоторые правила. Опять же, выяснить, как написать простой обратный вызов, было задачей настоящего исследователя.

Таким образом, переход от GWT RPC к RequestFactory далек от ситуации WIN-WIN, когда RPC в основном соответствует вашим потребностям. В итоге вы записываете тонны преобразований из объектов клиентского домена в прокси и наоборот. Но вы получаете некоторую гибкость и надежность своего решения. И поддержка на форуме отличная, в субботу тоже!

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

Honzajde
источник
Оформить заказ JBoss Erai. Мне нравится их подход к RPC.
Καrτhικ
6

Меня очень раздражает идея создания прокси-классов для всех моих сущностей. Мои pojos Hibernate / JPA автоматически генерируются из модели базы данных. Зачем мне теперь нужно создавать второе зеркало для RPC? У нас есть хороший фреймворк для «активации», который заботится о «выведении из спящего режима» pojos.

Кроме того, идея определения интерфейсов служб, которые не совсем реализуют службу на стороне сервера как java-контракт, но реализуют методы, для меня звучит очень J2EE 1.x / 2.x.

Καrτhικ
источник
5
Это раздражает, но если вам все равно нужно создавать прокси, вам нужна дополнительная помощь, которую RF дает вам для управления этими прокси. Не все хотят отправлять клиенту все pojo - например, рассмотрим игру в покер - ваш объект Player может содержать информацию, которую все должны видеть (количество карт в руке, количество открытых карт, общее количество фишек) и другую информацию, которая только один игрок должен видеть (закрытые карты).
Питер Рекор
Ваш пример с Покером действителен - мы работаем над этим, используя аннотации (@WireTransient), которые наша структура "estivation" использует для подавления значений.
Καrτhικ
4

В отличие от RequestFactory, который имеет плохие возможности обработки ошибок и тестирования (поскольку он обрабатывает большую часть материала под капотом GWT), RPC позволяет использовать более сервис-ориентированный подход. RequestFactory реализует более современный подход, основанный на внедрении зависимостей, который может предоставить полезный подход, если вам нужно вызвать сложные полиморфные структуры данных. При использовании RPC ваши структуры данных должны быть более плоскими, поскольку это позволит вашим утилитам маршалинга переводить между вашими моделями json / xml и java. Использование RPC также позволяет реализовать более надежную архитектуру, как указано в разделе gwt dev на веб-сайте Google.

"Простое развертывание клиент / сервер

Первый и самый простой способ думать об определениях служб - рассматривать их как всю серверную часть вашего приложения. С этой точки зрения клиентский код является вашим «внешним интерфейсом», а весь служебный код, который выполняется на сервере, является «внутренним». Если вы воспользуетесь этим подходом, ваши реализации службы будут иметь тенденцию быть более универсальными API, которые не будут тесно связаны с одним конкретным приложением. Определения ваших служб, вероятно, будут напрямую обращаться к базам данных через JDBC или Hibernate или даже к файлам в файловой системе сервера. Для многих приложений это представление подходит и может быть очень эффективным, поскольку сокращает количество уровней.

Многоуровневое развертывание

В более сложных многоуровневых архитектурах определения ваших служб GWT могут быть просто облегченными шлюзами, которые обращаются к средам внутренних серверов, таких как серверы J2EE. С этой точки зрения ваши сервисы можно рассматривать как «серверную половину» пользовательского интерфейса вашего приложения. Вместо того, чтобы быть универсальными, службы создаются для конкретных нужд вашего пользовательского интерфейса. Ваши сервисы становятся «интерфейсом» для «серверных» классов, которые записываются путем объединения вызовов к внутреннему уровню служб более общего назначения, реализованному, например, в виде кластера серверов J2EE. Такая архитектура подходит, если вам требуется, чтобы ваши внутренние службы работали на физически отдельном компьютере от вашего HTTP-сервера ».

Также обратите внимание, что для настройки одной службы RequestFactory требуется создать около 6 классов Java, тогда как для RPC требуется только 3. Больше кода == больше ошибок и сложности в моей книге.

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

Я также не верю, что службы RequestFactory являются сериализацией, как службы RPC.

В общем, после использования обоих в течение некоторого времени я всегда выбираю RPC, поскольку он более легкий, легче тестировать и отлаживать и быстрее, чем при использовании RequestFactory. Хотя RequestFactory может быть более элегантным и расширяемым, чем его аналог RPC. Дополнительная сложность не делает его лучшим инструментом.

Я считаю, что лучшая архитектура - это использование двух веб-приложений, одного клиента и одного сервера. Сервер представляет собой простое легкое универсальное веб-приложение на Java, использующее библиотеку servlet.jar. Клиент - GWT. Вы делаете RESTful-запрос через GWT-RPC на стороне сервера клиентского веб-приложения. Серверная сторона клиента - это просто переход к http-клиенту apache, который использует постоянный туннель в обработчик запросов, который вы запускаете как отдельный сервлет в веб-приложении сервлета сервера. Веб-приложение сервлета должно содержать уровень приложения вашей базы данных (hibernate, cayenne, sql и т. Д.). Это позволяет вам полностью отделить объектные модели базы данных от реального клиента, обеспечивая гораздо более расширяемый и надежный способ разработки и модульного тестирования вашего приложения. Конечно, для этого требуется немного времени на первоначальную настройку, но, в конце концов, позволяет создать динамическую фабрику запросов вне GWT. Это позволяет вам использовать лучшее из обоих миров. Не говоря уже о возможности тестировать и вносить изменения на стороне сервера без необходимости компиляции или сборки клиента gwt.

1-14x0R
источник
0

Я думаю, что это действительно полезно, если у вас есть тяжелое pojo на стороне клиента, например, если вы используете объекты Hibernate или JPA. Мы приняли другое решение, используя структуру персистентности в стиле Django с очень легкими объектами.

Уберто
источник
0

Единственное предостережение, которое я хотел бы сделать, заключается в том, что RequestFactory использует транспорт двоичных данных (возможно, deRPC?), А не обычный GWT-RPC.

Это имеет значение только в том случае, если вы проводите тяжелое тестирование с помощью SyncProxy, Jmeter, Fiddler или любого аналогичного инструмента, который может читать / оценивать содержимое HTTP-запроса / ответа (например, GWT-RPC), но будет более сложным с deRPC или RequestFactory.

Дхартфорд
источник
1
За исключением того, что на самом деле RequestFactory предоставляет "чистую Java" реализацию из коробки, без необходимости использования сторонних инструментов, таких как SyncProxy. См. Stackoverflow.com/questions/4853188/…
Томас Бройер,
0

В нашем проекте очень большая реализация GWT-RPC. Фактически у нас есть 50 сервисных интерфейсов со многими методами каждый, и у нас есть проблемы с размером TypeSerializer, сгенерированного компилятором, который делает наш JS-код огромным. Итак, мы анализируем, чтобы перейти к RequestFactory. Я пару дней читал, что копаюсь в сети и пытаюсь найти, что делают другие люди. Самый важный недостаток, который я видел, и, возможно, я мог ошибаться, заключается в том, что с RequestFactory вы больше не контролируете связь между объектами вашего домена сервера и вашими клиентскими объектами. Что нам нужно, так это применить шаблон загрузки / сохранения контролируемым образом. Я имею в виду, например, что клиент получает весь граф объектов, принадлежащих определенной транзакции, выполняет свои обновления, и они отправляют все обратно на сервер. Сервер будет отвечать за проверку, сравнение старых с новыми значениями и сохранение. Если 2 пользователя с разных сайтов получают одну и ту же транзакцию и делают некоторые обновления, полученная транзакция не должна быть объединенной. В моем сценарии одно из обновлений должно завершиться ошибкой. Я не вижу, чтобы RequestFactory помогала поддерживать такую ​​обработку.

С уважением Даниэль

Дэниел Ардисон
источник
Я разделяю эти опасения ... Вы в конечном итоге выбрали РФ?
HDave
0

Справедливо ли сказать, что при рассмотрении ограниченного приложения MIS, скажем, с 10-20 бизнес-объектами, поддерживающими CRUD и каждый из которых имеет ~ 1-10 свойств, на самом деле выбор маршрута зависит от личных предпочтений?

Если это так, то, возможно, прогнозирование масштабирования вашего приложения может стать ключом к выбору маршрута GWT RPC или RequestFactory:

  1. Ожидается, что мое приложение останется с этим относительно ограниченным количеством объектов, но будет значительно увеличиваться с точки зрения их числа. 10-20 объектов * 100 000 записей.

  2. Мое приложение будет значительно увеличиваться по количеству сущностей, но относительное количество каждой из них останется низким. 5000 объектов * 100 записей.

  3. Ожидается, что мое приложение останется с этим относительно ограниченным количеством объектов И останется в относительно небольшом количестве, например, 10-20 объектов * 100 записей.

В моем случае я нахожусь в самом начале попытки принять это решение. Еще больше усложняется тем, что необходимо изменить архитектуру пользовательского интерфейса на стороне клиента, а также сделать выбор транспорта. В моем предыдущем (значительно) крупномасштабном пользовательском интерфейсе GWT использовалась библиотека Hmvc4Gwt, которая была заменена средствами GWT MVP.

чили
источник