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?
gwt
gwt-rpc
requestfactory
Daghan ---
źródło
źródło
Odpowiedzi:
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ć
Person
klasę z kilkoma metodami pobierającymi i ustawiającymi oraz może z prostą logiką biznesową do dalszego dzielenia danych wPerson
obiekcie. 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,
PersonDTO
który przesłania rzeczywistyPerson
obiekt używany na serwerze. PoPersonDTO
prostu ma podzbiór pobierających i ustawiających obiektów po stronie serwera, „domena”Person
. Teraz trzeba napisać kod, który Marshalls danych międzyPerson
iPersonDTO
obiektu 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ą”,
EntityProxy
typ służy do uwidocznienia semantyki trwałej tożsamości danych w kodzie klienta. Proste obiekty są mapowane przy użyciuValueProxy
typu.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
ServiceLayer
zapewnia znacznie więcej punktów zaczepienia, aby dostosować jego zachowanie przez dodanieServiceLayerDecorator
wystąpień.źródło
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:
Wady GWT RPC:
Wady RequestFactory:
Zalety RequestFactory
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.
źródło
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.
źródło
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.
źródło
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.
źródło
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.
źródło
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
źródło
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:
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.
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.
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.
źródło