web-dev-qa-db-fra.com

Quand dois-je utiliser RequestFactory vs GWT-RPC?

J'essaie de savoir si je dois migrer mes appels gwt-rpc vers les nouveaux cals GWT2.1 RequestFactory.

La documentation de 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 de proxy qui simplifie la communication (vous ne passez pas dans les deux sens l'entité réelle mais juste le proxy, il est donc plus léger et plus facile à gérer)

Est-ce que c'est tout ou est-ce que je manque quelque chose d'autre dans la grande image?

87
Daghan ---

La grande différence entre GWT RPC et RequestFactory est que le système RPC est "RPC-by-concrete-type" tandis que RequestFactory est "RPC-by-interface".

RPC est plus pratique pour commencer, 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 classe Person avec un groupe de getters et de setters et peut-être une logique métier simple pour le découpage et le découpage des données dans l'objet Person. Cela fonctionne très bien jusqu'à ce que vous souhaitiez avoir du code spécifique au serveur, non compatible GWT, dans votre classe. Parce que le système RPC est basé sur le fait d'avoir le même type concret sur le client et le serveur, vous pouvez frapper un mur de complexité en fonction des capacités de votre client GWT.

Pour contourner l'utilisation de code incompatible, de nombreux utilisateurs finissent par créer un homologue PersonDTO qui masque le véritable objet Person utilisé sur le serveur. PersonDTO a juste un sous-ensemble des getters et setters de l'objet "domaine", Person côté serveur. Vous devez maintenant écrire du code qui rassemble les données entre l'objet Person et PersonDTO et tous les autres types d'objet que vous souhaitez transmettre au client.

RequestFactory commence en supposant que vos objets de 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 du 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 "Entités" ou "Objets avec identité et version", le type EntityProxy 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 du type ValueProxy.

Avec RequestFactory, vous payez un coût de démarrage initial pour s'adapter à des systèmes plus compliqués que GWT RPC ne prend facilement en charge. ServiceLayer de RequestFactory fournit beaucoup plus de hooks pour personnaliser son comportement en ajoutant des instances ServiceLayerDecorator .

73
BobV

Je suis passé par une transition de RPC à RF. Je dois d'abord dire que mon expérience est limitée en ce sens que j'ai utilisé autant d'entités proxies que 0.

Avantages de GWT RPC:

  • C'est très facile à installer, à comprendre et à APPRENDRE!
  • Les mêmes objets basés sur les classes sont utilisés sur le client et sur le serveur.
  • Cette approche permet d'économiser des tonnes de code.
  • Idéal, lorsque les mêmes objets de modèle (et POJOS) sont utilisés sur le client et le serveur, les POJO == MODEL OBJECTs == DTOs
  • Facile à déplacer des éléments du serveur vers le client.
  • Mise en œuvre facile à partager de la logique commune entre le client et le serveur (cela peut s'avérer un inconvénient critique lorsque vous avez besoin d'une logique différente).

Inconvénients de GWT RPC:

  • Impossible d'avoir une implémentation différente de certaines méthodes pour le serveur et le client, par exemple vous devrez peut-être utiliser une structure de journalisation différente sur le client et le serveur, ou une méthode d'égalité différente.
  • Implémentation REALY BAD qui n'est pas plus extensible: la plupart des fonctionnalités du serveur sont implémentées en tant que méthodes statiques sur une classe RPC. QUI SUCE VRAIMENT.
  • par exemple. Il est impossible d'ajouter un obscurcissement des erreurs côté serveur
  • Quelques problèmes de sécurité XSS qui ne sont pas résolus de manière très élégante, voir la documentation (je ne suis pas sûr que ce soit plus élégant pour RequestFactory)

Inconvénients de RequestFactory:

  • VRAIMENT DIFFICILE de comprendre du doc ​​officiel, quel est le mérite de celui-ci! Cela commence par un terme complètement trompeur PROXIES - ce sont en fait des DTO de RF qui sont créés par RF automatiquement. Les mandataires sont définis par des interfaces, par exemple @ProxyFor ( Journal.class). IDE vérifie s'il existe des méthodes correspondantes dans Journal. Voilà pour le mappage.
  • RF ne fera pas grand-chose pour vous en termes de points communs entre le client et le serveur car
  • Sur le client, vous devez convertir "PROXIES" en vos objets de domaine client et vice-versa. C'est complètement ridicule. Cela pourrait être fait en quelques lignes de code de manière déclarative, mais il n'y a AUCUN SUPPORT POUR CELA! Si seulement nous pouvions mapper nos objets de domaine avec des proxys plus élégamment, quelque chose comme la méthode JavaScript JSON.stringify (.. ,) est MANQUANT dans la boîte à outils RF).
  • N'oubliez pas que vous êtes également responsable de la définition récursive des propriétés transférables de vos objets de domaine sur les proxys.
  • MANIPULATION D'ERREUR PAUVRE sur le serveur et - Les traces de pile sont omises par défaut sur le serveur et vous obtenez des exceptions inutiles vides sur le client. Même lorsque j'ai défini un gestionnaire d'erreurs personnalisé, je n'ai pas pu accéder aux traces de pile de bas niveau! Terrible.
  • Quelques bugs mineurs dans IDE et ailleurs. J'ai déposé deux demandes de bogues qui ont été acceptées. Pas un Einstein n'était nécessaire pour comprendre qu'il s'agissait en fait de bogues.
  • DOCUMENTATION SUCE. Comme je l'ai mentionné, les procurations devraient être mieux expliquées, le terme est TROMPEUR. Pour les problèmes courants de base que je résolvais, DOCS IS INUTILE. Un autre exemple de malentendu du DOC est la connexion des annotations JPA à RF. Il semble des documents succincts qu'ils jouent un peu ensemble, et oui, il y a une question correspondante sur StackOverflow. Je recommande d'oublier toute "connexion" JPA avant de comprendre RF.

Avantages de RequestFactory

  • Excellent support de forum.
  • Le support IDE est assez bon (mais ce n'est pas un avantage contrairement à RPC)
  • Flexibilité de votre implémentation client et serveur (couplage lâche)
  • Des trucs fantaisistes, connectés à EntityProxies, au-delà des simples DTO - mise en cache, mises à jour partielles, très utiles pour les mobiles.
  • Vous pouvez utiliser ValueProxies comme le remplacement le plus simple des DTO (mais vous devez faire vous-même toutes les conversions pas si sophistiquées).
  • Prise en charge des validations de bean JSR-303.

Compte tenu des autres inconvénients du 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 moqué (par exemple localStorage), SOP est un problème.

  • Pas de prise en charge pour la configuration des tests - navigateur sans tête + serveur distant <= pas de test sans tête simple pour GWT, SOP.

  • Oui, il est possible d'exécuter des tests d'intégration Selenium (mais ce n'est pas ce que je veux)

  • JSNI est très puissant, mais lors de ces discussions brillantes 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 à RequestFactory est loin d'être une situation WIN-WIN, lorsque RPC correspond principalement à vos besoins. Vous finissez par écrire des tonnes de conversions d'objets de domaine client vers des proxys et vice-versa. Mais vous obtenez 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 vaut vraiment la peine 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.

28
honzajde

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'estimation" 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 comme un contrat Java mais implémentent les méthodes) me semble très J2EE 1.x/2.x.

6
Καrτhικ

Contrairement à RequestFactory qui a de faibles 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épendance plus moderne qui peut fournir une approche utile si vous devez invoquer 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 , tel que cité dans la section gwt dev du site Web de Google.

"Déploiement simple client/serveur

La première et la plus simple façon de penser aux définitions de service est de les traiter comme le back-end de votre application. De ce point de vue, le code côté client est votre "front-end" 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 auraient tendance à être des API plus générales qui ne sont pas étroitement couplées à une application spécifique. Vos définitions de service accéderaient probablement directement à des 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 à plusieurs niveaux plus complexes, vos définitions de service GWT pourraient simplement être des passerelles légères qui appellent des environnements de serveur 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 "front end" des classes "back end" qui sont écrites en assemblant les appels à une couche de services back-end plus générale, implémentée, par exemple, comme un cluster de serveurs J2EE. Ce type d'architecture est approprié si vous avez besoin que vos services principaux s'exécutent sur un ordinateur physiquement distinct de votre serveur HTTP. "

Notez également que la mise en place d'un seul service RequestFactory nécessite la création d'environ 6 Java classes où RPC en nécessite seulement 3. Plus de code == plus d'erreurs et de complexité dans mon livre.

RequestFactory a également un peu plus de temps lors du traitement des demandes, car il doit organiser la sérialisation entre les proxys de données et les modèles réels Java. Cette interface ajoutée ajoute des cycles de traitement supplémentaires qui peuvent vraiment s'additionner dans un environnement d'entreprise ou de production.

Je ne pense pas non plus que les services RequestFactory soient de la sérialisation comme les services RPC.

Dans l'ensemble, après avoir utilisé les deux pendant un certain temps maintenant, j'utilise toujours RPC comme son plus léger, plus facile à tester et à déboguer, et plus rapide que l'utilisation d'un 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, la meilleure architecture consiste à utiliser deux applications Web, un client et un serveur. Le serveur est un simple générique léger Java webapp qui utilise la bibliothèque servlet.jar. Le client est GWT. Vous effectuez une demande RESTful via GWT-RPC dans le côté serveur de l'application Web client. 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 demandes que vous exécutez en tant que servlet unique dans votre application Web de servlet de serveur. L'application Web de servlet doit contenir votre couche d'application de base de données (mise en veille prolongée, 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 unitaire votre application. Certes, cela nécessite un peu de temps de configuration initiale, mais dans la fin vous permet de créer une fabrique de requêtes dynamique en dehors de GWT. Cela vous permet de tirer le meilleur parti des deux mondes. Sans oublier de pouvoir tester et apporter des modifications à votre serveur sans avoir à avoir le client gwt comp iled ou construire.

4
1-14x0r

Je pense que c'est vraiment utile si vous avez un gros pojo côté client, par exemple si vous utilisez des entités Hibernate ou JPA. Nous avons adopté une autre solution, en utilisant un framework de persistance de style Django avec des entités très légères).

0
Uberto

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 transforme notre code JS en énorme. Nous sommes donc en train d'analyser pour évoluer vers RequestFactory. J'ai été lu pendant quelques jours en fouillant sur le Web et en essayant de trouver ce que font les autres. L'inconvénient le plus important que j'ai vu, et peut-être que je peux me tromper, c'est qu'avec RequestFactory, vous ne contrôlez plus la communication entre vos objets de domaine de serveur et ceux de votre client. Ce dont nous avons besoin, c'est d'appliquer le modèle de chargement/sauvegarde de manière contrôlée. Je veux dire, par exemple, le client reçoit le graphe d'objet entier des objets appartenant à une transaction spécifique, fait ses mises à jour et les renvoie 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 doit pas être la fusionnée. L'une des mises à jour devrait échouer dans mon scénario. Je ne vois pas que RequestFactory aide à prendre en charge ce type de traitement.

Cordialement Daniel

0
Daniel Ardison

Est-il juste de dire que lorsque l'on considère une application SIG limitée, disons avec 10-20 objets métier CRUD'ables, et chacun avec ~ 1-10 propriétés, que c'est vraiment à la préférence personnelle quelle route suivre?

Si oui, alors peut-être que la projection de la façon dont votre application va évoluer pourrait être la clé dans le choix de votre itinéraire GWT RPC ou RequestFactory:

  1. On s'attend à ce que ma candidature reste avec ce nombre relativement limité d'entités, mais augmentera massivement en termes de nombre. 10-20 objets * 100 000 enregistrements.

  2. Ma candidature va augmenter de manière significative dans l'étendue des entités mais le nombre relatif impliqué de chacune restera faible. 5000 objets * 100 enregistrements.

  3. On s'attend à ce que ma demande reste avec ce nombre relativement limité d'entités ET restera en nombre relativement faible, par ex. 10-20 objets * 100 enregistrements

Dans mon cas, je suis sur le point de commencer à essayer de prendre cette décision. Encore plus compliqué en devant changer l'architecture côté client de l'interface utilisateur ainsi qu'en faisant le choix de transport. Mon interface utilisateur GWT à grande échelle précédente (de manière significative) utilisait la bibliothèque Hmvc4Gwt, qui a été remplacée par les installations GWT MVP.

0
chillyspoon

La seule mise en garde que je voudrais apporter 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 demande/réponse HTTP (comme GWT-RPC), mais serait plus difficile avec deRPC ou RequestFactory.

0
dhartford