Коли слід використовувати RequestFactory проти GWT-RPC?


87

Я намагаюся зрозуміти, чи слід мігрувати свої дзвінки gwt-rpc до нових номерів GWT2.1 RequestFactory.

У документації Google неясно згадується, що RequestFactory є кращим методом зв'язку клієнт-сервер для "сервісів, орієнтованих на дані"

Що я можу вигадати з документації, так це те, що є новий клас Proxy, який спрощує спілкування (ви не передаєте туди-сюди фактичну сутність, а лише проксі-сервер, тому він має меншу вагу та простіше в управлінні)

У цьому вся суть або я щось ще не бачу у загальній картині?


8
так, це питання пов'язане з офіційним devguide 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. Ви просто заявляєте про властивості, які слід прочитати та записати за допомогою клієнтського коду в інтерфейсі проксі-сервера, а компоненти сервера RequestFactory подбають про маршування даних та виклик ваших методів обслуговування. Для програм, які мають чітко визначену концепцію "Сутності" або "Об'єкти з ідентифікацією та версією", EntityProxyтип використовується для викриття стійкої семантики ідентифікації ваших даних у коді клієнта. Прості об’єкти відображаються за допомогою ValueProxyтипу.

За допомогою RequestFactory ви платите попередню вартість запуску, щоб розмістити більш складні системи, ніж GWT RPC легко підтримує. RequestFactory ServiceLayerпропонує значно більше гачків для налаштування своєї поведінки, додаючи ServiceLayerDecoratorекземпляри.


Це вагомий привід підтримати моє рішення перейти на RequestFactory. Дякую, Боб! Це має сенс, і я не розумію, чому деякі люди кажуть: "в деяких випадках використовуйте RPC, а в інших - RF, залежно від ваших потреб", тому що, здається, для RPC потрібно писати багато клейового коду і цього шару DTO
Dan L.

5
Ще одним плюсом RequestFactory є те, що його можна використовувати з Android та GWT із точно таким самим кодом.
Патрік

28

Я пройшов перехід від RPC до РФ. Спочатку я повинен сказати, що мій досвід обмежений тим, що я використовував стільки EntityProxies, скільки 0.

Переваги RPT GWT:

  • Це дуже просто налаштувати, зрозуміти та НАВЧИТИСЯ!
  • На клієнті та на сервері використовуються однакові об'єкти на основі класу.
  • Такий підхід економить тонни коду.
  • Ідеально, коли однакові об’єкти моделі (і POJOS) використовуються на клієнті та сервері, POJO == MODEL OBJECTs == DTO
  • Легко переміщувати речі з сервера на клієнта.
  • Легко ділитися реалізацією загальної логіки між клієнтом і сервером (це може виявитись критичним недоліком, коли потрібна інша логіка).

Недоліки GWT RPC:

  • Неможливо по-різному реалізувати деякі методи для сервера та клієнта, наприклад, вам може знадобитися використовувати іншу структуру ведення журналу на клієнті та сервері, або інший метод equals.
  • РЕАЛЬНО ПОГОРАНА реалізація, яка не підлягає подальшому розширенню: більшість функціональних можливостей сервера реалізовано як статичні методи на класі RPC. ЩО ДЕЙСТВОРНО СУГО.
  • Наприклад, неможливо додати затухання помилок на стороні сервера
  • Деякі проблеми безпеки XSS, які не зовсім елегантно вирішувані, див. Документи (я не впевнений, що це більш елегантно для RequestFactory)

Недоліки RequestFactory:

  • ДІЙСНО ТВОРДО зрозуміти з офіційного документа, в чому його заслуга! Починається з абсолютно оманливого терміну PROXIES - це насправді DTO RF, які створюються RF автоматично. Проксі-сервери визначаються інтерфейсами, наприклад @ProxyFor (Journal.class). IDE перевіряє, чи існують відповідні методи в журналі. Стільки про картографування.
  • РФ не буде робити багато для вас з точки зору спільності клієнта та сервера, тому що
  • На клієнті вам потрібно перетворити "PROXIES" на об'єкти домену вашого клієнта і навпаки. Це абсолютно смішно. Це можна зробити в декількох рядках коду декларативно, але для цього немає ПІДТРИМКИ! Якби ми могли б більш елегантно зіставити наші доменні об’єкти з проксі-серверами, щось на зразок методу JavaScript JSON.stringify (.. ,,) ПРОПУСКУЄ в RF toolbox.
  • Не забувайте, ви також несете відповідальність за встановлення переданих властивостей об'єктів домену проксі-серверам тощо, і так далі.
  • БІДНА ОБРОБКА ПОМИЛОК на сервері та - Трасування стеків за замовчуванням пропущено на сервері, і ви отримуєте порожні марні винятки на клієнті. Навіть коли я встановив спеціальний обробник помилок, я не зміг дістатися до слідів стеків низького рівня! Жахливий.
  • Деякі незначні помилки в підтримці IDE та в інших місцях. Я подав два запити на помилки, які були прийняті. Не потрібно було Ейнштейна, щоб зрозуміти, що це насправді помилки.
  • ДОКУМЕНТАЦІЯ СМОК. Як я вже згадував про довірених осіб, слід пояснити їх краще, цей термін ОЗНАЧАЄ. Що стосується основних загальних проблем, які я вирішував, DOCS БЕЗКОШТОВНИЙ. Іншим прикладом непорозуміння з боку DOC є підключення анотацій JPA до РФ. З лаконічних документів видно, що вони начебто грають разом, і так, є відповідне запитання щодо StackOverflow. Я рекомендую забути будь-яке `` з'єднання '' JPA, перш ніж розуміти РФ.

Переваги RequestFactory

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

Беручи до уваги інші недоліки ГВТ загалом:

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

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

  • Так, можна запускати тести інтеграції селену (але це не те, що я хочу)

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

Таким чином, перехід від GWT RPC до RequestFactory далекий від ситуації WIN-WIN, коли RPC здебільшого відповідає вашим потребам. У підсумку ви записуєте тонни перетворень із об’єктів домену клієнта в проксі-сервери і навпаки. Але ви отримуєте певну гнучкість та надійність вашого рішення. І підтримка на форумі відмінна, і в суботу також!

Беручи до уваги всі переваги та недоліки, про які я щойно згадав, варто по-справжньому добре подумати заздалегідь, чи справді будь-який із цих підходів покращує ваше рішення та налаштування вашого розвитку без великих компромісів.


Оформити замовлення JBoss Erai. Мені подобається їхній підхід до RPC.
ταrτhικ

6

Мені здається, ідея створення проксі-класів для всіх моїх сутностей досить дратує. Мої поджі Hibernate / JPA автоматично генеруються з моделі бази даних. Чому мені зараз потрібно створити друге дзеркало таких для RPC? У нас є приємний фреймворк, який піклується про дегібернацію пожо.

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


5
Це дратує, але якщо вам все одно доведеться створювати проксі-сервери, то ви скоріше отримаєте додаткову допомогу, яку RF надає вам для управління цими проксі. Не всі хочуть відправити клієнту ціле подзо - наприклад, розгляньте гру в покер - ваш об'єкт Player може мати інформацію, яку всі повинні бачити (кількість карт в руках, карти, що показують догори, загальна кількість фішок) та іншу інформацію, яка лише один гравець повинен бачити (картки лицьовою стороною вниз).
Peter Recore

Ваш приклад з покером є дійсним - ми обходимо це, маючи анотації (@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 counter. Додана складність не робить його кращим інструментом необхідним.

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


0

Я думаю, що це дійсно корисно, якщо у вас важке подзо на стороні клієнта, наприклад, якщо ви використовуєте 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 службових інтерфейсів з багатьма методами, і у нас проблеми з розміром TypeSerializers, сформованим компілятором, що робить наш код JS величезним. Тож ми аналізуємо, щоб рухатися до RequestFactory. Мене пару днів читали, копаючись в Інтернеті та намагаючись знайти, що роблять інші люди. Найважливішим недоліком, який я бачив, і, можливо, я можу помилятися, є те, що за допомогою RequestFactory ви більше не контролюєте зв'язок між об'єктами вашого домену сервера та вашими клієнтськими. Нам потрібно застосувати шаблон завантаження / збереження контрольованим способом. Я маю на увазі, наприклад, клієнт отримує весь графік об’єктів об’єктів, що належать до певної транзакції, робить його оновлення, і вони відправляють ціле назад на сервер. Сервер відповідає за перевірку, порівняння старих із новими значеннями та стійкість. Якщо 2 користувачі з різних сайтів отримують одну і ту ж транзакцію та роблять деякі оновлення, отримана транзакція не повинна бути об’єднаною. Одне з оновлень повинно вийти з ладу в моєму сценарії. Я не бачу, що RequestFactory допомагає підтримувати такий вид обробки.

З повагою, Данило


Я поділяю ці занепокоєння ... Ви в підсумку пішли з РФ?
HDзберегти

0

Чи справедливо сказати, що, розглядаючи обмежену програму MIS, скажімо, з 10–20 CRUD-об’єктами бізнес-об’єктів, і кожен із ~ 1–10 властивостями, що насправді це залежить від особистих переваг, яким шляхом рухатись?

Якщо так, то, можливо, проектування того, як масштабуватиметься ваша програма, може бути ключовим при виборі маршруту GWT RPC або RequestFactory:

  1. Очікується, що моя заявка залишатиметься з відносно обмеженою кількістю організацій, але значно збільшиться з точки зору їх кількості. 10-20 об'єктів * 100 000 записів.

  2. Моя заявка збирається суттєво збільшити обсяги сутностей, але відносна кількість залучених кожної з них залишатиметься низькою. 5000 об'єктів * 100 записів.

  3. Очікується, що моя програма залишатиметься з відносно обмеженою кількістю об'єктів І буде залишатися у відносно низькій кількості, наприклад 10-20 об'єктів * 100 записів

У моєму випадку я перебуваю у самій вихідній точці, намагаючись прийняти це рішення. Надалі ускладнюється необхідністю змінити архітектуру на стороні клієнтського інтерфейсу, а також зробити вибір транспорту. У моєму попередньому (суттєво) широкомасштабному інтерфейсі GWT використовувалася бібліотека Hmvc4Gwt, яка була замінена засобами GVT MVP.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.