Kiedy należy używać RequestFactory, a kiedy GWT-RPC?


87

Próbuję dowiedzieć się, czy powinienem przeprowadzić migrację wywołań gwt-rpc do nowych kalendarzy GWT2.1 RequestFactory.

Dokumentacja Google niejasno wspomina, że ​​RequestFactory jest lepszą metodą komunikacji klient-serwer dla „usług zorientowanych na dane”

Z dokumentacji mogę wydobyć to, że istnieje nowa klasa Proxy, która upraszcza komunikację (nie przekazuje się tam iz powrotem rzeczywistej jednostki, ale tylko proxy, dzięki czemu jest lżejszy i łatwiejszy w zarządzaniu)

Czy o to chodzi, czy też brakuje mi czegoś innego w dużym obrazie?


8
tak, link do tego pytania pochodzi z oficjalnego przewodnika GWT !
törzsmókus

Odpowiedzi:


73

Duża różnica między GWT RPC i RequestFactory polega na tym, że system RPC jest typu „RPC według konkretnego typu”, podczas gdy RequestFactory to „RPC według interfejsu”.

RPC jest wygodniejszy na początku, ponieważ piszesz mniej wierszy kodu i używasz tej samej klasy zarówno na kliencie, jak i na serwerze. Możesz utworzyć Personklasę z kilkoma metodami pobierającymi i ustawiającymi oraz może z prostą logiką biznesową do dalszego dzielenia danych w Personobiekcie. Działa to całkiem dobrze, dopóki nie będziesz chciał mieć specyficznego dla serwera, niekompatybilnego z GWT kodu wewnątrz swojej klasy. Ponieważ system RPC opiera się na posiadaniu tego samego typu betonu zarówno na kliencie, jak i na serwerze, możesz trafić w ścianę złożoności w oparciu o możliwości klienta GWT.

Aby obejść użycie niekompatybilnego kodu, wielu użytkowników kończy tworzenie peera, PersonDTOktóry przesłania rzeczywisty Personobiekt używany na serwerze. Po PersonDTOprostu ma podzbiór pobierających i ustawiających obiektów po stronie serwera, „domena” Person. Teraz trzeba napisać kod, który Marshalls danych między Personi PersonDTOobiektu i wszystkich innych typów obiektów, które chcesz przekazać do klienta.

RequestFactory zaczyna się od założenia, że ​​obiekty domeny nie będą zgodne z GWT. Po prostu deklarujesz właściwości, które powinny być odczytywane i zapisywane przez kod klienta w interfejsie Proxy, a komponenty serwera RequestFactory zajmują się organizowaniem danych i wywoływaniem metod usługi. W przypadku aplikacji, które mają dobrze zdefiniowaną koncepcję „jednostek” lub „obiektów z tożsamością i wersją”, EntityProxytyp służy do uwidocznienia semantyki trwałej tożsamości danych w kodzie klienta. Proste obiekty są mapowane przy użyciu ValueProxytypu.

Dzięki RequestFactory płacisz z góry koszty uruchomienia, aby dostosować się do bardziej skomplikowanych systemów niż te obsługiwane przez GWT RPC. RequestFactory ServiceLayerzapewnia znacznie więcej punktów zaczepienia, aby dostosować jego zachowanie przez dodanie ServiceLayerDecoratorwystąpień.


To dobry powód, aby poprzeć moją decyzję o przejściu na RequestFactory. Dziękuję Bob! To ma sens i nie rozumiem, dlaczego niektórzy mówią „używaj RPC w niektórych przypadkach, a RF w innych, w zależności od potrzeb”, ponieważ wygląda na to, że w przypadku RPC musisz napisać dużo kodu kleju i tę warstwę DTO
Dan L.

5
Kolejną zaletą RequestFactory jest to, że można go używać z systemem Android i GWT z dokładnie tym samym kodem.
Patrick,

28

Przeszedłem przez przejście z RPC na RF. Po pierwsze, muszę powiedzieć, że moje doświadczenie jest ograniczone w tym, że użyłem tylu EntityProxies, co 0.

Zalety GWT RPC:

  • Konfiguracja, zrozumienie i NAUKA są bardzo łatwe!
  • Te same obiekty oparte na klasach są używane na kliencie i na serwerze.
  • Takie podejście pozwala zaoszczędzić mnóstwo kodu.
  • Idealne, gdy te same obiekty modelu (i POJOS) są używane na kliencie i serwerze, POJOs == MODEL OBJECTs == DTOs
  • Łatwe przenoszenie rzeczy z serwera do klienta.
  • Łatwe współdzielenie implementacji wspólnej logiki między klientem a serwerem (może to okazać się krytyczną wadą, gdy potrzebujesz innej logiki).

Wady GWT RPC:

  • Nie można mieć różnych implementacji niektórych metod dla serwera i klienta, np. Może być konieczne użycie innej struktury rejestrowania na kliencie i serwerze lub innej metody równości.
  • NAPRAWDĘ ZŁA implementacja, której nie można dalej rozszerzać: większość funkcji serwera jest zaimplementowana jako metody statyczne w klasie RPC. TO NAPRAWDĘ DO BANIA.
  • np. nie można dodać zaciemniania błędów po stronie serwera
  • Niektóre problemy związane z bezpieczeństwem XSS, które nie są do końca elegancko rozwiązane, zobacz dokumentację (nie jestem pewien, czy jest to bardziej eleganckie dla RequestFactory)

Wady RequestFactory:

  • NAPRAWDĘ trudno zrozumieć z oficjalnego dokumentu, jaka to zasługa! Zaczyna się od całkowicie wprowadzającego w błąd terminu PROXIES - w rzeczywistości są to DTO RF, które są tworzone automatycznie przez RF. Serwery proxy są definiowane przez interfejsy, np. @ProxyFor (Journal.class). IDE sprawdza, czy istnieją odpowiednie metody w dzienniku. Tyle jeśli chodzi o mapowanie.
  • RF niewiele dla Ciebie zrobi pod względem cech wspólnych klienta i serwera, ponieważ
  • Na kliencie musisz przekonwertować „PROXIES” na obiekty domeny klienta i odwrotnie. To jest całkowicie śmieszne. Można to zrobić w kilku wierszach kodu deklaratywnie, ale NIE MA WSPARCIA! Gdybyśmy tylko mogli bardziej elegancko zmapować nasze obiekty domeny na serwery proxy, brakuje czegoś takiego jak metoda JavaScript JSON.stringify (.. ,,) w zestawie narzędzi RF.
  • Nie zapominaj, że jesteś również odpowiedzialny za ustawianie przenoszalnych właściwości obiektów domeny na serwery proxy i tak dalej rekurencyjnie.
  • SŁABA OBSŁUGA BŁĘDÓW na serwerze i - Ślady stosu są domyślnie pomijane na serwerze i otrzymujesz puste, bezużyteczne wyjątki na kliencie. Nawet gdy ustawiłem niestandardową obsługę błędów, nie byłem w stanie uzyskać dostępu do śladów stosu niskiego poziomu! Straszny.
  • Kilka drobnych błędów w obsłudze IDE i nie tylko. Złożyłem dwie prośby o błędy, które zostały zaakceptowane. Żaden Einstein nie był potrzebny, aby dowiedzieć się, że w rzeczywistości były to błędy.
  • DOKUMENTACJA DOBRA. Jak wspomniałem, proxy powinno być lepiej wyjaśnione, termin to MISLEADING. W przypadku podstawowych problemów, które rozwiązywałem, DOCS JEST BEZ UŻYCIA. Innym przykładem nieporozumienia ze strony DOC jest połączenie adnotacji JPA z RF. Ze zwięzłych dokumentów wynika, że ​​grają razem i tak, jest odpowiednie pytanie na StackOverflow. Zalecam zapomnieć o każdym „połączeniu” JPA przed zrozumieniem RF.

Zalety RequestFactory

  • Doskonałe wsparcie na forum.
  • Obsługa IDE jest całkiem dobra (ale nie jest zaletą w porównaniu z RPC)
  • Elastyczność implementacji Twojego klienta i serwera (luźne połączenie)
  • Fantazyjne rzeczy, połączone z EntityProxies, poza prostymi DTO - buforowanie, częściowe aktualizacje, bardzo przydatne na urządzeniach mobilnych.
  • Możesz użyć ValueProxies jako najprostszego zamiennika DTO (ale wszystkie niezbyt wyszukane konwersje musisz wykonać samodzielnie).
  • Wsparcie dla walidacji Bean JSR-303.

Biorąc pod uwagę ogólnie inne wady GWT:

  • Niemożliwe jest uruchomienie testów integracyjnych (kod klienta GWT + zdalny serwer) z zapewnioną obsługą JUnit <= wszystkie JSNI muszą być mockowane (np. LocalStorage), problem stanowi SOP.

  • Brak wsparcia dla konfiguracji testowej - bezgłowa przeglądarka + zdalny serwer <= brak prostego bezgłowego testowania dla GWT, SOP.

  • Tak, można przeprowadzić testy integracji selenu (ale nie tego chcę)

  • JSNI jest bardzo potężne, ale podczas tych błyskotliwych przemówień, które wygłaszają na konferencjach, nie mówią zbyt wiele o tym, że pisanie kodów JSNI ma również pewne zasady. Ponownie, wymyślenie, jak napisać proste wywołanie zwrotne, było zadaniem wartym prawdziwego badacza.

Podsumowując, przejście z GWT RPC do RequestFactory jest dalekie od sytuacji WIN-WIN, kiedy RPC w większości odpowiada Twoim potrzebom. W końcu piszesz mnóstwo konwersji z obiektów domeny klienta na serwery proxy i odwrotnie. Ale zyskujesz pewną elastyczność i solidność swojego rozwiązania. A wsparcie na forum jest doskonałe, także w sobotę!

Biorąc pod uwagę wszystkie zalety i wady, o których wspomniałem, naprawdę dobrze jest pomyśleć z wyprzedzeniem, czy którekolwiek z tych podejść rzeczywiście przynosi ulepszenia do rozwiązania i konfiguracji programowania bez dużych kompromisów.


Zamówienie JBoss Erai. Uwielbiam ich podejście do RPC.
Καrτhικ

6

Pomysł tworzenia klas proxy dla wszystkich moich podmiotów jest dość denerwujący. Moje pojosy Hibernate / JPA są automatycznie generowane na podstawie modelu bazy danych. Dlaczego muszę teraz utworzyć drugą kopię lustrzaną tych dla RPC? Mamy fajny framework "estywacji", który zajmuje się "de-hibernacją" pojos.

Pomysł definiowania interfejsów usług, które nie do końca implementują usługę po stronie serwera jako kontrakt java, ale implementują metody - brzmi dla mnie bardzo J2EE 1.x / 2.x.


5
To denerwujące, ale jeśli i tak musisz tworzyć serwery proxy, wolałbyś mieć dodatkową pomoc, jaką daje RF do zarządzania tymi serwerami proxy. Nie każdy chce wysłać całe pojo do klienta - na przykład rozważ grę w pokera - Twój obiekt gracza może zawierać informacje, które każdy powinien zobaczyć (liczba kart w ręku, odkryte karty, całkowita liczba żetonów) i inne informacje, które tylko jeden gracz powinien zobaczyć (zakryte karty).
Peter Recore

Twój przykład w pokerze jest prawidłowy - omijamy to, mając adnotacje (@WireTransient), których używa nasza struktura „estivation” do tłumienia wartości.
Καrτhικ

4

W przeciwieństwie do RequestFactory, który ma słabą obsługę błędów i możliwości testowania (ponieważ przetwarza większość rzeczy pod maską GWT), RPC pozwala na zastosowanie podejścia bardziej zorientowanego na usługi. RequestFactory implementuje bardziej nowoczesne podejście stylizowane na iniekcję zależności, które może zapewnić przydatne podejście, jeśli musisz wywołać złożone polimorficzne struktury danych. Podczas korzystania z RPC struktury danych będą musiały być bardziej płaskie, ponieważ umożliwi to narzędziom kierującym tłumaczenie między modelami json / xml i java. Korzystanie z RPC pozwala również na implementację bardziej niezawodnej architektury, o której mowa w sekcji gwt dev w witrynie Google.

„Proste wdrożenie klienta / serwera

Pierwszym i najprostszym sposobem myślenia o definicjach usług jest traktowanie ich jako całego zaplecza aplikacji. Z tego punktu widzenia kod po stronie klienta jest „interfejsem użytkownika”, a cały kod usługi działający na serwerze jest „zapleczem”. Jeśli zastosujesz takie podejście, implementacje usług będą miały tendencję do bardziej ogólnego przeznaczenia interfejsów API, które nie są ściśle powiązane z jedną konkretną aplikacją. Definicje usług prawdopodobnie miałyby bezpośredni dostęp do baz danych przez JDBC lub Hibernate lub nawet do plików w systemie plików serwera. W przypadku wielu aplikacji ten widok jest odpowiedni i może być bardzo wydajny, ponieważ zmniejsza liczbę warstw.

Wdrożenie wielopoziomowe

W bardziej złożonych, wielowarstwowych architekturach definicje usług GWT mogą być po prostu lekkimi bramami, które łączą się ze środowiskami serwerów zaplecza, takimi jak serwery J2EE. Z tego punktu widzenia usługi można postrzegać jako „połowę serwera” interfejsu użytkownika aplikacji. Zamiast pełnić funkcję ogólnego przeznaczenia, usługi są tworzone pod kątem konkretnych potrzeb interfejsu użytkownika. Twoje usługi stają się „frontendem” dla klas „zaplecza”, które są zapisywane przez zszywanie razem wywołań do warstwy usług zaplecza bardziej ogólnego przeznaczenia, zaimplementowanej, na przykład, jako klaster serwerów J2EE. Ten rodzaj architektury jest odpowiedni, jeśli chcesz, aby usługi zaplecza działały na fizycznie oddzielnym komputerze od serwera HTTP ”.

Zauważ również, że skonfigurowanie pojedynczej usługi RequestFactory wymaga stworzenia około 6 klas java, podczas gdy RPC wymaga tylko 3. Więcej kodu == więcej błędów i złożoności w mojej książce.

RequestFactory ma również nieco większy narzut podczas przetwarzania żądania, ponieważ musi organizować serializację między serwerami proxy danych a rzeczywistymi modelami Java. Ten dodany interfejs dodaje dodatkowe cykle przetwarzania, które mogą naprawdę sumować się w przedsiębiorstwie lub środowisku produkcyjnym.

Nie wierzę również, że usługi RequestFactory są serializacją, tak jak usługi RPC.

Podsumowując, po tym, jak od jakiegoś czasu używam obu, zawsze wybieram RPC, ponieważ jest lżejszy, łatwiejszy do testowania i debugowania oraz szybszy niż przy użyciu RequestFactory. Chociaż RequestFactory może być bardziej elegancki i rozszerzalny niż jego część odpowiadająca RPC. Dodatkowa złożoność nie sprawia, że ​​jest to potrzebne lepsze narzędzie.

Moim zdaniem najlepszą architekturą jest wykorzystanie dwóch aplikacji internetowych, jednego klienta i jednego serwera. Serwer jest prostą, lekką, ogólną aplikacją internetową java, która korzysta z biblioteki servlet.jar. Klient jest GWT. Wysyłasz żądanie RESTful za pośrednictwem GWT-RPC po stronie serwera aplikacji internetowej klienta. Strona serwera klienta jest tylko przejściem do klienta HTTP Apache, który używa trwałego tunelu do procedury obsługi żądań, którą uruchomiłeś jako pojedynczy serwlet w aplikacji WWW serwletu serwera. Aplikacja internetowa serwletu powinna zawierać warstwę aplikacji bazy danych (hibernacja, cayenne, sql itp.). Pozwala to w pełni oddzielić modele obiektów bazy danych od rzeczywistego klienta, zapewniając znacznie bardziej rozszerzalny i niezawodny sposób tworzenia i testowania jednostkowego aplikacji. To prawda, wymaga trochę czasu na wstępną konfigurację, ale ostatecznie umożliwia utworzenie dynamicznej fabryki żądań znajdującej się poza GWT. Pozwala to wykorzystać to, co najlepsze z obu światów. Nie wspominając o możliwości testowania i wprowadzania zmian po stronie serwera bez konieczności kompilowania lub budowania klienta gwt.


0

Myślę, że jest to bardzo pomocne, jeśli masz duże pojo po stronie klienta, na przykład jeśli używasz jednostek Hibernate lub JPA. Przyjęliśmy inne rozwiązanie, używając struktury trwałości w stylu Django z bardzo lekkimi encjami.


0

Jedynym zastrzeżeniem, które chciałbym umieścić, jest to, że RequestFactory używa binarnego transportu danych (może deRPC?), A nie zwykłego GWT-RPC.

Ma to znaczenie tylko wtedy, gdy przeprowadzasz ciężkie testy za pomocą SyncProxy, Jmeter, Fiddler lub innego podobnego narzędzia, które może odczytać / ocenić zawartość żądania / odpowiedzi HTTP (jak GWT-RPC), ale byłoby trudniejsze w przypadku deRPC lub RequestFactory.


1
Tyle że w rzeczywistości RequestFactory zapewnia implementację „czystej Javy” zaraz po wyjęciu z pudełka, bez potrzeby stosowania narzędzi innych firm, takich jak SyncProxy. Zobacz stackoverflow.com/questions/4853188/…
Thomas Broyer

0

W naszym projekcie mamy bardzo dużą implementację GWT-RPC. Właściwie mamy 50 interfejsów usługi z wieloma metodami każda i mamy problemy z rozmiarem TypeSerializerów generowanych przez kompilator, który zmienia nasz kod JS na ogromny. Więc analizujemy, aby przejść do RequestFactory. Czytano mnie przez kilka dni, gdy kopałem w sieci i próbowałem dowiedzieć się, co robią inni ludzie. Najważniejszą wadą, jaką zauważyłem, i być może mogę się mylić, jest to, że dzięki RequestFactory nie masz już kontroli nad komunikacją między obiektami domeny serwera a obiektami klienta. Potrzebujemy zastosowania schematu ładowania / zapisywania w kontrolowany sposób. Mam na myśli np. Że klient otrzymuje graf całego obiektu obiektów należących do określonej transakcji, dokonuje jego aktualizacji i odsyła całość z powrotem na serwer. Serwer będzie odpowiedzialny za sprawdzanie poprawności, porównywanie starych z nowymi wartościami i wytrwałość. Jeśli 2 użytkowników z różnych witryn otrzyma tę samą transakcję i dokona aktualizacji, wynikowa transakcja nie powinna być transakcją scaloną. W moim scenariuszu jedna z aktualizacji powinna się nie powieść. Nie widzę, żeby RequestFactory pomagało w obsłudze tego rodzaju przetwarzania.

Pozdrawiam Daniela


Podzielam te obawy ... czy skończyłeś z RF?
HDave

0

Czy można uczciwie powiedzieć, że rozważając ograniczoną aplikację MIS, powiedzmy z 10-20 obiektami biznesowymi CRUD i każdy z ~ 1-10 właściwościami, to naprawdę zależy od osobistych preferencji, którą drogą wybrać?

Jeśli tak, to być może prognozowanie, w jaki sposób aplikacja będzie skalować, może być kluczem do wyboru trasy GWT RPC lub RequestFactory:

  1. Oczekuje się, że moja aplikacja pozostanie przy tej stosunkowo ograniczonej liczbie podmiotów, ale znacznie wzrośnie ich liczba. 10-20 obiektów * 100 000 rekordów.

  2. Moja aplikacja znacznie wzrośnie w zakresie podmiotów, ale względne liczby każdego z nich pozostaną niskie. 5000 obiektów * 100 rekordów.

  3. Oczekuje się, że moja aplikacja pozostanie przy tej stosunkowo ograniczonej liczbie podmiotów ORAZ pozostanie w stosunkowo małej liczbie np. 10-20 obiektów * 100 rekordów

W moim przypadku jestem na samym początku próby podjęcia tej decyzji. Jeszcze bardziej skomplikowane przez konieczność zmiany architektury interfejsu użytkownika po stronie klienta, a także dokonanie wyboru transportu. Mój poprzedni (znacząco) duży interfejs użytkownika GWT korzystał z biblioteki Hmvc4Gwt, która została zastąpiona przez narzędzia GWT MVP.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.