Ich versuche herauszufinden, ob ich meine gwt-rpc-Aufrufe auf die neuen GWT2.1 RequestFactory-Kaliber migrieren soll.
In der Google-Dokumentation wird vage erwähnt, dass RequestFactory eine bessere Client-Server-Kommunikationsmethode für "datenorientierte Dienste" ist.
Was ich aus der Dokumentation entnehmen kann, ist, dass es eine neue Proxy-Klasse gibt, die die Kommunikation vereinfacht (Sie geben nicht die eigentliche Entität hin und her, sondern nur den Proxy, sodass sie leichter und einfacher zu verwalten ist).
Ist das der springende Punkt oder fehlt mir noch etwas im großen Ganzen?
gwt
gwt-rpc
requestfactory
Daghan ---
quelle
quelle
Antworten:
Der große Unterschied zwischen GWT RPC und RequestFactory besteht darin, dass das RPC-System "RPC-by-Concrete-Type" ist, während RequestFactory "RPC-by-Interface" ist.
Der Einstieg in RPC ist bequemer, da Sie weniger Codezeilen schreiben und dieselbe Klasse sowohl auf dem Client als auch auf dem Server verwenden. Sie können eine
Person
Klasse mit einer Reihe von Gettern und Setzern und einer einfachen Geschäftslogik erstellen, um die Daten imPerson
Objekt weiter aufzuteilen und in Würfel zu schneiden . Dies funktioniert so gut, bis Sie einen serverspezifischen, nicht GWT-kompatiblen Code in Ihrer Klasse haben möchten. Da das RPC-System darauf basiert, dass sowohl auf dem Client als auch auf dem Server derselbe konkrete Typ vorhanden ist, können Sie auf der Grundlage der Funktionen Ihres GWT-Clients auf eine Komplexitätswand stoßen.Um die Verwendung von inkompatiblem Code zu umgehen, erstellen viele Benutzer einen Peer
PersonDTO
, derPerson
das auf dem Server verwendete reale Objekt beschattet . Das hatPersonDTO
nur eine Teilmenge der Getter und Setter des serverseitigen "Domain"Person
-Objekts. Nun müssen Sie Code , dass marshalls Daten zwischen den Schreib-Person
undPersonDTO
Objekt und alle anderen Objekttypen , die Sie an den Client übergeben werden soll.RequestFactory geht zunächst davon aus, dass Ihre Domänenobjekte nicht GWT-kompatibel sind. Sie deklarieren einfach die Eigenschaften, die vom Clientcode in einer Proxy-Schnittstelle gelesen und geschrieben werden sollen, und die RequestFactory-Serverkomponenten kümmern sich um das Marshalling der Daten und das Aufrufen Ihrer Dienstmethoden. Für Anwendungen mit einem genau definierten Konzept von "Entitäten" oder "Objekten mit Identität und Version" wird der
EntityProxy
Typ verwendet, um die persistente Identitätssemantik Ihrer Daten für den Clientcode verfügbar zu machen. Einfache Objekte werden mithilfe desValueProxy
Typs zugeordnet.Mit RequestFactory zahlen Sie im Voraus Startkosten für kompliziertere Systeme, als GWT RPC problemlos unterstützt. RequestFactory
ServiceLayer
bietet deutlich mehr Hooks, um das Verhalten durch Hinzufügen vonServiceLayerDecorator
Instanzen anzupassen .quelle
Ich habe einen Übergang von RPC zu RF durchlaufen. Zuerst muss ich sagen, dass meine Erfahrung darin begrenzt ist. Ich habe so viele EntityProxies wie 0 verwendet.
Vorteile von GWT RPC:
Nachteile von GWT RPC:
Nachteile von RequestFactory:
Vorteile von RequestFactory
Berücksichtigung anderer Nachteile von GWT im Allgemeinen:
Integrationstests (GWT-Clientcode + Remote-Server) mit bereitgestellter JUnit-Unterstützung können nicht ausgeführt werden. <= Alle JSNI müssen verspottet werden (z. B. localStorage). SOP ist ein Problem.
Keine Unterstützung für Test-Setup - Headless-Browser + Remote-Server <= Kein einfacher Headless-Test für GWT, SOP.
Ja, es ist möglich, Selen-Integrationstests durchzuführen (aber das ist nicht das, was ich will).
JSNI ist sehr mächtig, aber bei diesen glänzenden Vorträgen, die sie auf Konferenzen halten, reden sie nicht viel darüber, dass das Schreiben von JSNI-Codes einige Regeln hat. Wiederum war es eine Aufgabe eines echten Forschers, herauszufinden, wie man einen einfachen Rückruf schreibt.
Zusammenfassend ist der Übergang von GWT RPC zu RequestFactory weit entfernt von der WIN-WIN-Situation, in der RPC hauptsächlich Ihren Anforderungen entspricht. Am Ende schreiben Sie Tonnenkonvertierungen von Clientdomänenobjekten zu Proxys und umgekehrt. Sie erhalten jedoch eine gewisse Flexibilität und Robustheit Ihrer Lösung. Und die Unterstützung im Forum ist auch am Samstag hervorragend!
In Anbetracht aller Vor- und Nachteile, die ich gerade erwähnt habe, lohnt es sich, im Voraus zu überlegen, ob einer dieser Ansätze tatsächlich zu einer Verbesserung Ihrer Lösung und Ihres Entwicklungsaufbaus führt, ohne große Kompromisse einzugehen.
quelle
Ich finde die Idee, Proxy-Klassen für alle meine Entitäten zu erstellen, ziemlich ärgerlich. Meine Hibernate / JPA-Pojos werden automatisch aus dem Datenbankmodell generiert. Warum muss ich jetzt einen zweiten Spiegel für RPC erstellen? Wir haben ein schönes "Estivation" -Rahmenwerk, das sich um das "Entschlafen" der Pojos kümmert.
Auch die Idee, Dienstschnittstellen zu definieren, die den serverseitigen Dienst nicht ganz als Java-Vertrag implementieren, aber die Methoden implementieren, klingt für mich sehr nach J2EE 1.x / 2.x.
quelle
Im Gegensatz zu RequestFactory mit schlechten Funktionen zur Fehlerbehandlung und zum Testen (da die meisten Dinge unter der Haube von GWT verarbeitet werden) können Sie mit RPC einen serviceorientierteren Ansatz verwenden. RequestFactory implementiert einen moderneren Ansatz im Stil der Abhängigkeitsinjektion, der einen nützlichen Ansatz bietet, wenn Sie komplexe polymorphe Datenstrukturen aufrufen müssen. Wenn Sie RPC verwenden, müssen Ihre Datenstrukturen flacher sein, da dies Ihren Marshalling-Dienstprogrammen ermöglicht, zwischen Ihren json / xml- und Java-Modellen zu übersetzen. Mit RPC können Sie auch eine robustere Architektur implementieren, wie im Abschnitt gwt dev auf der Google-Website angegeben.
"Einfache Client / Server-Bereitstellung
Die erste und einfachste Möglichkeit, sich Service-Definitionen vorzustellen, besteht darin, sie als das gesamte Back-End Ihrer Anwendung zu behandeln. Aus dieser Perspektive ist clientseitiger Code Ihr "Front-End" und der gesamte auf dem Server ausgeführte Service-Code ist "Back-End". Wenn Sie diesen Ansatz wählen, handelt es sich bei Ihren Service-Implementierungen in der Regel um allgemeinere APIs, die nicht eng an eine bestimmte Anwendung gekoppelt sind. Ihre Dienstdefinitionen greifen wahrscheinlich direkt über JDBC oder Hibernate oder sogar auf Dateien im Dateisystem des Servers auf Datenbanken zu. Für viele Anwendungen ist diese Ansicht geeignet und kann sehr effizient sein, da sie die Anzahl der Ebenen verringert.
Multi-Tier-Bereitstellung
In komplexeren, mehrstufigen Architekturen können Ihre GWT-Dienstdefinitionen einfach einfache Gateways sein, die Back-End-Serverumgebungen wie J2EE-Server aufrufen. Aus dieser Perspektive können Ihre Dienste als "Serverhälfte" der Benutzeroberfläche Ihrer Anwendung angesehen werden. Anstatt universell zu sein, werden Dienste für die spezifischen Anforderungen Ihrer Benutzeroberfläche erstellt. Ihre Dienste werden zum "Front-End" für die "Back-End" -Klassen, die durch Zusammenfügen von Aufrufen an eine allgemeinere Back-End-Schicht von Diensten geschrieben werden, die beispielsweise als Cluster von J2EE-Servern implementiert sind. Diese Art von Architektur ist geeignet, wenn Ihre Back-End-Dienste auf einem physisch von Ihrem HTTP-Server getrennten Computer ausgeführt werden müssen. "
Beachten Sie auch, dass zum Einrichten eines einzelnen RequestFactory-Dienstes etwa 6 Java-Klassen erstellt werden müssen, für die als RPC nur 3 erforderlich sind. Mehr Code == mehr Fehler und Komplexität in meinem Buch.
RequestFactory hat auch etwas mehr Overhead während der Anforderungsverarbeitung, da die Serialisierung zwischen den Datenproxys und den tatsächlichen Java-Modellen gemarshallt werden muss. Diese zusätzliche Schnittstelle fügt zusätzliche Verarbeitungszyklen hinzu, die sich in einer Unternehmens- oder Produktionsumgebung wirklich summieren können.
Ich glaube auch nicht, dass RequestFactory-Dienste Serialisierung wie RPC-Dienste sind.
Alles in allem, nachdem ich beide seit einiger Zeit verwendet habe, verwende ich RPC immer als leichter, einfacher zu testen und zu debuggen und schneller als mit einer RequestFactory. Obwohl RequestFactory möglicherweise eleganter und erweiterbarer ist als sein RPC-Gegenstück. Die zusätzliche Komplexität macht es nicht zu einem besseren Werkzeug.
Meiner Meinung nach besteht die beste Architektur darin, zwei Web-Apps, einen Client und einen Server, zu verwenden. Der Server ist eine einfache, leichtgewichtige generische Java-Webanwendung, die die Bibliothek servlet.jar verwendet. Der Kunde ist GWT. Sie stellen eine RESTful-Anforderung über GWT-RPC auf der Serverseite der Client-Webanwendung. Die Serverseite des Clients ist jedoch nur ein Durchgang zum Apache-HTTP-Client, der einen dauerhaften Tunnel in den Anforderungshandler verwendet, den Sie als einzelnes Servlet in Ihrer Server-Servlet-Webanwendung ausführen. Die Servlet-Webanwendung sollte Ihre Datenbankanwendungsschicht enthalten (Ruhezustand, Cayennepfeffer, SQL usw.). Auf diese Weise können Sie die Datenbankobjektmodelle vollständig vom eigentlichen Client trennen und so Ihre Anwendung wesentlich erweiterbarer und robuster entwickeln und testen. Zugegeben, es erfordert ein bisschen anfängliche Einrichtungszeit. Am Ende können Sie jedoch eine dynamische Anforderungsfactory außerhalb von GWT erstellen. So können Sie das Beste aus beiden Welten nutzen. Ganz zu schweigen davon, dass Sie Ihre Serverseite testen und Änderungen daran vornehmen können, ohne dass der GWT-Client kompiliert oder erstellt werden muss.
quelle
Ich denke, es ist wirklich hilfreich, wenn Sie auf der Clientseite ein starkes Pojo haben, zum Beispiel wenn Sie Hibernate- oder JPA-Entitäten verwenden. Wir haben eine andere Lösung gewählt, die ein Persistenz-Framework im Django-Stil mit sehr leichten Einheiten verwendet.
quelle
Die einzige Einschränkung, die ich einfügen würde, ist, dass RequestFactory den binären Datentransport (deRPC vielleicht?) Und nicht den normalen GWT-RPC verwendet.
Dies ist nur wichtig, wenn Sie umfangreiche Tests mit SyncProxy, Jmeter, Fiddler oder einem ähnlichen Tool durchführen, das den Inhalt der HTTP-Anforderung / Antwort lesen / auswerten kann (wie GWT-RPC), mit deRPC oder RequestFactory jedoch eine größere Herausforderung darstellen.
quelle
Wir haben eine sehr große Implementierung von GWT-RPC in unserem Projekt. Tatsächlich haben wir 50 Service-Schnittstellen mit jeweils vielen Methoden, und wir haben Probleme mit der Größe der vom Compiler generierten TypeSerializer, die unseren JS-Code riesig machen. Wir analysieren also, um auf RequestFactory umzusteigen. Ich bin seit ein paar Tagen gelesen worden, habe mich im Internet umgesehen und versucht herauszufinden, was andere Leute tun. Der wichtigste Nachteil, den ich gesehen habe, und vielleicht könnte ich mich irren, ist, dass Sie mit RequestFactory nicht mehr die Kontrolle über die Kommunikation zwischen Ihren Server Domain-Objekten und Ihren Client-Objekten haben. Wir müssen das Lade- / Speichermuster kontrolliert anwenden. Ich meine, zum Beispiel empfängt der Client das gesamte Objektdiagramm von Objekten, die zu einer bestimmten Transaktion gehören, führt seine Aktualisierungen durch und sie senden das gesamte an den Server zurück. Der Server ist für die Validierung verantwortlich, vergleicht alte mit neuen Werten und führt die Persistenz durch. Wenn 2 Benutzer von verschiedenen Sites dieselbe Transaktion erhalten und einige Aktualisierungen vornehmen, sollte die resultierende Transaktion nicht die zusammengeführte sein. Eines der Updates sollte in meinem Szenario fehlschlagen. Ich sehe nicht, dass RequestFactory diese Art der Verarbeitung unterstützt.
Grüße Daniel
quelle
Ist es fair zu sagen, dass es bei der Betrachtung einer eingeschränkten MIS-Anwendung, beispielsweise mit 10-20 CRUD-fähigen Geschäftsobjekten und jeweils mit ~ 1-10 Eigenschaften, wirklich auf die persönlichen Vorlieben ankommt, welchen Weg man einschlägt?
Wenn ja, könnte die Projektion der Skalierung Ihrer Anwendung möglicherweise der Schlüssel für die Auswahl Ihrer Route GWT RPC oder RequestFactory sein:
Es wird erwartet, dass meine Bewerbung bei dieser relativ begrenzten Anzahl von Unternehmen bleibt, aber in Bezug auf ihre Anzahl massiv zunimmt. 10-20 Objekte * 100.000 Datensätze.
Meine Bewerbung wird in der Breite der Entitäten erheblich zunehmen, aber die relativen Zahlen der einzelnen Entitäten werden niedrig bleiben. 5000 Objekte * 100 Datensätze.
Es wird erwartet, dass meine Anwendung bei dieser relativ begrenzten Anzahl von Entitäten bleibt UND in einer relativ geringen Anzahl von z. B. 10-20 Objekten * 100 Datensätzen bleibt
In meinem Fall bin ich am Anfang des Versuchs, diese Entscheidung zu treffen. Noch komplizierter, da die clientseitige Architektur der Benutzeroberfläche geändert und die Transportauswahl getroffen werden muss. Meine vorherige (signifikant) groß angelegte GWT-Benutzeroberfläche verwendete die Hmvc4Gwt-Bibliothek, die durch die GWT-MVP-Einrichtungen ersetzt wurde.
quelle