J'essaie de déterminer si je dois migrer mes appels gwt-rpc vers les nouveaux cals GWT2.1 RequestFactory.
La documentation Google mentionne vaguement que RequestFactory est une meilleure méthode de communication client-serveur pour les "services orientés données"
Ce que je peux distiller de la documentation, c'est qu'il existe une nouvelle classe Proxy qui simplifie la communication (vous ne passez pas dans les deux sens l'entité réelle mais juste le proxy, donc c'est plus léger et plus facile à gérer)
Est-ce là tout l'intérêt ou est-ce que je rate quelque chose d'autre dans le tableau d'ensemble?
gwt
gwt-rpc
requestfactory
Daghan ---
la source
la source
Réponses:
La grande différence entre GWT RPC et RequestFactory est que le système RPC est "RPC-by-concret-type" tandis que RequestFactory est "RPC-by-interface".
RPC est plus pratique pour démarrer, car vous écrivez moins de lignes de code et utilisez la même classe sur le client et le serveur. Vous pouvez créer une
Person
classe avec un tas de getters et de setters et peut-être une logique métier simple pour un découpage plus approfondi des données dans lePerson
objet. Cela fonctionne assez bien jusqu'à ce que vous finissiez par vouloir avoir du code spécifique au serveur, non compatible avec GWT, dans votre classe. Étant donné que le système RPC est basé sur le même type de béton sur le client et le serveur, vous pouvez atteindre un mur de complexité basé sur les capacités de votre client GWT.Pour contourner l'utilisation de code incompatible, de nombreux utilisateurs finissent par créer un pair
PersonDTO
qui fait de l'ombre à l'Person
objet réel utilisé sur le serveur. LePersonDTO
just a un sous-ensemble des getters et des setters de l'objet côté serveur, "domain"Person
. Maintenant , vous devez écrire du code que les données de Marshalls entre lePerson
etPersonDTO
objet et tous les autres types d'objets que vous souhaitez passer au client.RequestFactory commence par supposer que les objets de votre domaine ne seront pas compatibles GWT. Vous déclarez simplement les propriétés qui doivent être lues et écrites par le code client dans une interface Proxy, et les composants serveur RequestFactory se chargent de marshaler les données et d'appeler vos méthodes de service. Pour les applications qui ont un concept bien défini d '"Entités" ou "Objets avec identité et version", le
EntityProxy
type est utilisé pour exposer la sémantique d'identité persistante de vos données au code client. Les objets simples sont mappés à l'aide duValueProxy
type.Avec RequestFactory, vous payez un coût de démarrage initial pour accueillir des systèmes plus compliqués que ce que GWT RPC prend facilement en charge. RequestFactory
ServiceLayer
fournit beaucoup plus de hooks pour personnaliser son comportement en ajoutant desServiceLayerDecorator
instances.la source
J'ai traversé une transition de RPC à RF. Tout d'abord, je dois dire que mon expérience est limitée en cela, j'ai utilisé autant d'EntityProxies que 0.
Avantages de GWT RPC:
Inconvénients de GWT RPC:
Inconvénients de RequestFactory:
Avantages de RequestFactory
Compte tenu des autres inconvénients de GWT en général:
Impossible d'exécuter des tests d'intégration (code client GWT + serveur distant) avec le support JUnit fourni <= tout JSNI doit être simulé (par exemple localStorage), SOP est un problème.
Pas de support pour la configuration des tests - navigateur sans tête + serveur distant <= pas de test simple sans tête pour GWT, SOP.
Oui, il est possible d'exécuter des tests d'intégration au sélénium (mais ce n'est pas ce que je souhaite)
JSNI est très puissant, mais lors de ces brillantes discussions qu'ils donnent lors de conférences, ils ne parlent pas beaucoup du fait que l'écriture de codes JSNI a également des règles. Encore une fois, trouver comment écrire un simple rappel était une tâche digne d'un vrai chercheur.
En résumé, la transition de GWT RPC vers RequestFactory est loin d'être une situation WIN-WIN, lorsque RPC répond principalement à vos besoins. Vous finissez par écrire des tonnes de conversions d'objets du domaine client vers des proxys et vice-versa. Mais vous bénéficiez d'une certaine flexibilité et robustesse de votre solution. Et le support sur le forum est excellent, samedi aussi!
Compte tenu de tous les avantages et inconvénients que je viens de mentionner, il est très utile de penser à l'avance si l'une de ces approches apporte réellement une amélioration à votre solution et à votre configuration de développement sans grands compromis.
la source
Je trouve l'idée de créer des classes Proxy pour toutes mes entités assez ennuyeuse. Mes pojos Hibernate / JPA sont générés automatiquement à partir du modèle de base de données. Pourquoi dois-je maintenant créer un deuxième miroir de ceux pour RPC? Nous avons un joli cadre "d'estivation" qui s'occupe de "déshiberner" les pojos.
De plus, l'idée de définir des interfaces de service qui n'implémentent pas tout à fait le service côté serveur en tant que contrat Java mais implémentent les méthodes - me semble très J2EE 1.x / 2.x.
la source
Contrairement à RequestFactory qui a de mauvaises capacités de gestion des erreurs et de test (car il traite la plupart des choses sous le capot de GWT), RPC vous permet d'utiliser une approche plus orientée service. RequestFactory implémente une approche de style d'injection de dépendances plus moderne qui peut fournir une approche utile si vous devez appeler des structures de données polymorphes complexes. Lorsque vous utilisez RPC, vos structures de données devront être plus plates, car cela permettra à vos utilitaires de marshaling de traduire entre vos modèles json / xml et java. L'utilisation de RPC vous permet également de mettre en œuvre une architecture plus robuste, comme indiqué dans la section gwt dev sur le site Web de Google.
"Déploiement client / serveur simple
La première et la plus simple façon de penser aux définitions de service est de les traiter comme l'ensemble du back-end de votre application. De ce point de vue, le code côté client est votre "frontal" et tout le code de service qui s'exécute sur le serveur est "back-end". Si vous adoptez cette approche, vos implémentations de service auront tendance à être des API plus générales qui ne sont pas étroitement associées à une application spécifique. Vos définitions de service accèderaient probablement directement aux bases de données via JDBC ou Hibernate ou même à des fichiers dans le système de fichiers du serveur. Pour de nombreuses applications, cette vue est appropriée et elle peut être très efficace car elle réduit le nombre de niveaux.
Déploiement à plusieurs niveaux
Dans des architectures plus complexes et à plusieurs niveaux, vos définitions de service GWT peuvent simplement être des passerelles légères qui font appel à des environnements de serveurs principaux tels que des serveurs J2EE. De ce point de vue, vos services peuvent être considérés comme la «moitié serveur» de l'interface utilisateur de votre application. Au lieu d'être à usage général, les services sont créés pour les besoins spécifiques de votre interface utilisateur. Vos services deviennent le "frontal" des classes "back-end" qui sont écrites en assemblant des appels à une couche de services back-end plus générale, implémentée, par exemple, sous la forme d'un cluster de serveurs J2EE. Ce type d'architecture est approprié si vous avez besoin que vos services back-end s'exécutent sur un ordinateur physiquement séparé de votre serveur HTTP. "
Notez également que la mise en place d'un seul service RequestFactory nécessite de créer environ 6 classes java alors que RPC ne nécessite que 3. Plus de code == plus d'erreurs et de complexité dans mon livre.
RequestFactory a également un peu plus de temps système pendant le traitement de la demande, car il doit rassembler la sérialisation entre les proxys de données et les modèles Java réels. Cette interface ajoutée ajoute des cycles de traitement supplémentaires qui peuvent vraiment s'additionner dans une entreprise ou un environnement de production.
Je ne crois pas non plus que les services RequestFactory soient une sérialisation comme les services RPC.
Dans l'ensemble, après avoir utilisé les deux pendant un certain temps maintenant, j'utilise toujours RPC car il est plus léger, plus facile à tester et à déboguer, et plus rapide que l'utilisation d'une RequestFactory. Bien que RequestFactory puisse être plus élégant et extensible que son homologue RPC. La complexité supplémentaire n'en fait pas un meilleur outil nécessaire.
Mon avis est que la meilleure architecture consiste à utiliser deux applications Web, un client et un serveur. Le serveur est une simple application web java générique légère qui utilise la bibliothèque servlet.jar. Le client est GWT. Vous effectuez une requête RESTful via GWT-RPC dans le côté serveur de l'application Web cliente. Le côté serveur du client n'est qu'un passage vers le client Apache http qui utilise un tunnel persistant dans le gestionnaire de requêtes que vous exécutez en tant que servlet unique dans votre application Web de servlet serveur. L'application Web servlet doit contenir la couche d'application de votre base de données (hibernate, cayenne, sql, etc.). Cela vous permet de séparer complètement les modèles d'objet de base de données du client réel, offrant un moyen beaucoup plus extensible et robuste de développer et de tester l'unité de votre application. Certes, cela nécessite un peu de temps de configuration initiale, mais à la fin vous permet de créer une usine de requêtes dynamiques en dehors de GWT. Cela vous permet de tirer parti du meilleur des deux mondes. Sans oublier de pouvoir tester et apporter des modifications à votre serveur sans avoir à faire compiler ou construire le client gwt.
la source
Je pense que c'est vraiment utile si vous avez un gros problème côté client, par exemple si vous utilisez des entités Hibernate ou JPA. Nous avons adopté une autre solution, utilisant un framework de persistance de style Django avec des entités très légères.
la source
La seule mise en garde que je ferais est que RequestFactory utilise le transport de données binaires (deRPC peut-être?) Et non le GWT-RPC normal.
Cela n'a d'importance que si vous effectuez des tests intensifs avec SyncProxy, Jmeter, Fiddler ou tout autre outil similaire capable de lire / évaluer le contenu de la requête / réponse HTTP (comme GWT-RPC), mais serait plus difficile avec deRPC ou RequestFactory.
la source
Nous avons une très grande implémentation de GWT-RPC dans notre projet. En fait, nous avons 50 interfaces de service avec de nombreuses méthodes chacune, et nous avons des problèmes avec la taille des TypeSerializers générés par le compilateur qui rend notre code JS énorme. Nous sommes donc en train de passer à RequestFactory. On me lit depuis quelques jours en train de fouiller sur le Web et d'essayer de trouver ce que font les autres. L'inconvénient le plus important que j'ai vu, et peut-être que je pourrais me tromper, est qu'avec RequestFactory, vous ne contrôlez plus la communication entre vos objets de domaine serveur et ceux de vos clients. Ce dont nous avons besoin, c'est d'appliquer le modèle de chargement / enregistrement de manière contrôlée. Je veux dire, par exemple, le client reçoit le graphe d'objets entier des objets appartenant à une transaction spécifique, effectue ses mises à jour et les renvoie le tout au serveur. Le serveur sera responsable de la validation, de la comparaison des anciennes avec les nouvelles valeurs et de la persistance. Si 2 utilisateurs de sites différents obtiennent la même transaction et effectuent des mises à jour, la transaction résultante ne devrait pas être celle fusionnée. L'une des mises à jour devrait échouer dans mon scénario. Je ne vois pas que RequestFactory aide à supporter ce type de traitement.
Cordialement Daniel
la source
Est-il juste de dire que lorsqu'on considère une application MIS limitée, par exemple avec 10 à 20 objets métier CRUD'able, et chacun avec ~ 1-10 propriétés, cela dépend vraiment de la préférence personnelle de l'itinéraire à suivre?
Si tel est le cas, alors peut-être que la projection de la façon dont votre application va évoluer pourrait être la clé du choix de votre itinéraire GWT RPC ou RequestFactory:
On s'attend à ce que ma candidature reste avec ce nombre relativement limité d'entités, mais elle augmentera massivement en termes de nombre. 10-20 objets * 100 000 enregistrements.
Ma candidature va augmenter considérablement dans la largeur des entités, mais le nombre relatif de chacune d'entre elles restera faible. 5000 objets * 100 enregistrements.
On s'attend à ce que mon application reste avec ce nombre relativement limité d'entités ET restera dans un nombre relativement faible, par exemple 10 à 20 objets * 100 enregistrements
Dans mon cas, je suis au tout début d'essayer de prendre cette décision. Plus compliqué par la nécessité de changer l'architecture côté client de l'interface utilisateur et de faire le choix du transport. Mon ancienne interface utilisateur GWT à grande échelle (significativement) utilisait la bibliothèque Hmvc4Gwt, qui a été remplacée par les installations MVP de GWT.
la source