J’essaie de savoir si je devrais 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 Proxy qui simplifie la communication (vous ne faites pas de va-et-vient de l’entité réelle mais seulement du proxy, elle est donc plus légère et plus facile à gérer).
Est-ce le point ou est-ce que je manque quelque chose d’autre dans la grande image?
La grande différence entre GWT RPC et RequestFactory est que le système RPC est “RPC-by-concrete-type” alors 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 à la fois sur le client et sur 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 un découpage et un découpage plus poussés des données dans l’object Person
. Cela fonctionne assez bien jusqu’à ce que vous souhaitiez avoir un 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 concret à la fois sur le client et sur le serveur, vous pouvez atteindre un mur de complexité en fonction des capacités de votre client GWT.
Pour contourner l’utilisation de code incompatible, de nombreux utilisateurs PersonDTO
par créer un pair PersonDTO
qui PersonDTO
l’object réel Person
utilisé sur le serveur. Le PersonDTO
juste un sous-ensemble des PersonDTO
getters et setters du côté serveur, “domain”, object Person
. Vous devez maintenant écrire le code qui regroupe les données entre l’object Person
et PersonDTO
et tous les autres types d’objects que vous souhaitez transmettre au client.
RequestFactory commence par supposer que vos objects de domaine ne seront pas compatibles avec 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 veillent à marshaler les données et à 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 objects simples sont mappés en utilisant le type ValueProxy
.
Avec RequestFactory, vous payez un coût de démarrage initial pour prendre en charge des systèmes plus complexes que ceux que GWT RPC prend facilement en charge. ServiceLayer de RequestFactory fournit beaucoup plus de hooks pour personnaliser son comportement en ajoutant des instances de ServiceLayerDecorator
.
Je suis passé d’une transition de RPC à RF. D’abord, je dois dire que mon expérience est limitée dans ce domaine, j’ai utilisé autant d’entité Proxies que 0.
Avantages de GWT RPC:
Inconvénients de GWT RPC:
Inconvénients de RequestFactory:
Avantages de RequestFactory
Considérant d’autres inconvénients de la 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), le SOP pose 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 de selenium (mais ce n’est pas ce que je veux)
JSNI est très puissant, mais lors des discussions shinyes qu’ils donnent lors de conférences, ils ne parlent pas beaucoup de ce que l’écriture de codes JSNI comporte également certaines règles. Encore une fois, déterminer 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 de la situation WIN-WIN, lorsque RPC répond le mieux à vos besoins. Vous finissez par écrire des tonnes de conversions à partir d’objects de domaine client en proxies 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 est très utile de penser à l’avance si l’une de ces approches apporte réellement des améliorations à votre solution et à votre configuration de développement sans grands compromis.
Je trouve très gênant l’idée de créer des classes de proxy pour toutes mes entités. Mes pojos Hibernate / JPA sont générés automatiquement à partir du modèle de firebase database. Pourquoi dois-je maintenant créer un deuxième miroir de ceux pour RPC? Nous avons un joli cadre “d’estivation” qui consiste à “désengager” les pojos.
En outre, 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émente les méthodes – me semble très J2EE 1.x / 2.x.
Contrairement à RequestFactory qui dispose de faibles capacités de traitement des erreurs et de test (puisqu’il traite la plupart des éléments sous le capot de GWT), RPC vous permet d’utiliser une approche plus orientée service. RequestFactory implémente une approche plus moderne de type dependency injection qui peut fournir une approche utile si vous avez besoin d’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, citée dans la section gwt dev du site Web de Google.
“Déploiement Simple Client / Serveur
La manière la plus simple et la plus simple de penser aux définitions de service est de les traiter comme l’ensemble du back-end de votre application. Dans cette perspective, le code côté client est votre “frontal” et tout code de service exécuté sur le serveur est “back end”. Si vous adoptez cette approche, vos implémentations de services auront tendance à être des API plus générales qui ne sont pas étroitement lié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 du système de fichiers du serveur. Pour de nombreuses applications, cette vue est appropriée et peut être très efficace car elle réduit le nombre de niveaux.
Déploiement à plusieurs niveaux
Dans les architectures multiniveaux plus complexes, vos définitions de service GWT pourraient simplement être des passerelles légères qui appellent des environnements de serveurs principaux tels que des serveurs J2EE. De ce sharepoint vue, vos services peuvent être considérés comme la “moitié serveur” de l’interface utilisateur de votre application. Au lieu d’être polyvalents, les services sont créés pour les besoins spécifiques de votre interface utilisateur. Vos services deviennent le “front-end” des classes “back-end” écrites en assemblant les appels à une couche de services back-end plus polyvalente, implémentée, par exemple, en tant que cluster de serveurs J2EE. Ce type d’architecture est approprié si vous souhaitez que vos services principaux s’exécutent sur un ordinateur physiquement distinct de votre serveur HTTP. ”
Notez également que la configuration d’un service RequestFactory unique nécessite la création d’environ 6 classes java où RPC ne requirejs que 3 classes supplémentaires. Plus de code == plus d’erreurs et de complexité dans mon livre.
RequestFactory a également un peu plus de charge lors du traitement de la requête, car il doit marshaler la sérialisation entre les proxy de données et les modèles Java réels. Cette interface supplémentaire ajoute des cycles de traitement supplémentaires qui peuvent vraiment s’append dans une entreprise ou un environnement de production.
Je ne crois pas non plus que les services RequestFactory soient des services de sérialisation tels que les services RPC.
Dans l’ensemble, après avoir utilisé les deux pendant un certain temps maintenant, je vais toujours avec RPC comme plus léger, plus facile à tester et à déboguer, et plus rapide que d’utiliser un RequestFactory. Bien que RequestFactory puisse être plus élégant et plus extensible que son compteur RPC. La complexité supplémentaire ne le rend 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 du côté serveur de l’application Web client. Le côté serveur du client est simplement un client HTTP pass-to-apache qui utilise un tunnel persistant dans le gestionnaire de requêtes que vous utilisez 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 firebase database (hibernate, cayenne, sql, etc.). Cela vous permet de séparer complètement les modèles d’object de firebase database du client réel. Certes, il nécessite un peu de temps de configuration initiale, mais à la fin, vous pouvez créer une fabrique de requêtes dynamic en dehors de GWT. Cela vous permet de tirer parti du meilleur des deux mondes. Sans compter que vous pouvez tester et apporter des modifications à votre serveur sans avoir à comstackr ou à comstackr le client gwt.
Je pense que cela est vraiment utile si vous avez un gros point sur le 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 seule mise en garde est que RequestFactory utilise le transport de données binarys (deRPC peut-être?) Et non le GWT-RPC normal.
Cela importe uniquement 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.
Nous avons une très grande implémentation de GWT-RPC dans notre projet. En fait, nous avons 50 interfaces de service avec beaucoup de méthodes chacune, et nous avons des problèmes avec la taille de TypeSerializers générée par le compilateur qui rend notre code JS énorme. Nous nous attendons donc à passer à RequestFactory. J’ai été lu pendant quelques jours en cherchant sur le Web et en essayant de trouver ce que font les autres. L’inconvénient le plus important que j’ai constaté, et peut-être que je pourrais me tromper, est que, avec RequestFactory, vous ne contrôlez plus la communication entre vos objects de domaine de serveur et ceux de vos clients. Nous avons besoin d’appliquer le modèle de chargement / sauvegarde de manière contrôlée. Je veux dire, par exemple, que le client reçoit le graphe d’object entier d’objects appartenant à une transaction spécifique, effectue ses mises à jour et les renvoie au serveur. Le serveur sera responsable de la validation, de la comparaison avec les nouvelles valeurs et de la persistance. Si 2 utilisateurs de sites différents reçoivent la même transaction et effectuent des mises à jour, la transaction qui en résulte ne doit pas être la même. 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
Est-il juste de dire que lorsque l’on considère une application MIS limitée, par exemple avec 10 à 20 objects métier CRUD, et chacun avec environ 1 à 10 propriétés, c’est vraiment à votre préférence personnelle de choisir la route à suivre?
Si c’est le cas, alors peut-être que la projection de votre application à l’échelle pourrait être la clé pour choisir votre itinéraire GWT RPC ou RequestFactory:
Mon application devrait restr avec ce nombre relativement limité d’entités, mais leur nombre augmentera considérablement. 10-20 objects * 100 000 enregistrements.
Mon application va considérablement augmenter dans l’ensemble des entités, mais le nombre relatif de chacun restra faible. 5000 objects * 100 enregistrements.
Mon application devrait restr avec ce nombre relativement restreint d’entités ET restra dans un nombre relativement faible, par exemple de 10 à 20 objects * 100 enregistrements
Dans mon cas, je suis au tout début du fait d’essayer de prendre cette décision. Plus compliqué par la nécessité de modifier l’architecture côté client de l’interface utilisateur et de faire le choix du transport. Mon ancienne interface utilisateur GWT à grande échelle utilisait la bibliothèque Hmvc4Gwt, qui a été remplacée par les fonctionnalités MVP de GWT.