gwt gwt-rpc requestfactory

¿Cuándo debería usar RequestFactory vs GWT-RPC?



(8)

Estoy intentando averiguar si debo migrar mis llamadas gwt-rpc a las nuevas llamadas GWT2.1 RequestFactory.

La documentación de Google menciona vagamente que RequestFactory es un mejor método de comunicación cliente-servidor para los "servicios orientados a datos"

Lo que puedo extraer de la documentación es que hay una nueva clase Proxy que simplifica la comunicación (no se pasa la entidad real sino solo el proxy, por lo que es más liviana y fácil de administrar)

¿Es ese el punto o me estoy perdiendo algo más en el panorama general?


¿Es justo decir que cuando se considera una aplicación MIS limitada, digamos con 10-20 objetos comerciales CRUD''able, y cada uno con ~ 1-10 propiedades, realmente depende de la preferencia personal qué ruta tomar?

Si es así, quizás la clave para elegir su ruta GWT RPC o RequestFactory sea proyectar cómo va a escalar su aplicación:

  1. Se espera que mi aplicación permanezca con ese número relativamente limitado de entidades, pero aumentará enormemente en términos de sus números. 10-20 objetos * 100,000 registros.

  2. Mi aplicación va a aumentar significativamente en la amplitud de las entidades, pero los números relativos involucrados de cada uno se mantendrán bajos. 5000 objetos * 100 registros.

  3. Se espera que mi aplicación permanezca con ese número relativamente limitado de entidades Y permanecerá en un número relativamente bajo de, por ejemplo, 10-20 objetos * 100 registros

En mi caso, estoy en el mismo punto de partida para tratar de tomar esta decisión. Más complicado aún al tener que cambiar la arquitectura del lado del cliente de la interfaz de usuario y al elegir el transporte. Mi IU de GWT (a gran escala) anterior utilizó la biblioteca Hmvc4Gwt, que ha sido reemplazada por las instalaciones GWT MVP.


A diferencia de RequestFactory que tiene capacidades de manejo y prueba de errores deficientes (ya que procesa la mayoría de las cosas bajo el capó de GWT), RPC le permite utilizar un enfoque más orientado al servicio. RequestFactory implementa un enfoque de estilo de inyección de dependencia más moderno que puede proporcionar un enfoque útil si necesita invocar estructuras de datos polimórficos complejos. Al usar RPC, sus estructuras de datos necesitarán ser más planas, ya que esto permitirá que sus utilidades de mapeo traduzcan entre sus modelos json / xml y java. El uso de RPC también le permite implementar una arquitectura más robusta, como se cita en la sección de desarrollo gwt en el sitio web de Google.

"Despliegue simple de cliente / servidor

La primera y más directa forma de pensar en las definiciones de servicios es tratarlos como el back-end completo de la aplicación. Desde esta perspectiva, el código del lado del cliente es su "interfaz" y todo el código de servicio que se ejecuta en el servidor es "back-end". Si toma este enfoque, las implementaciones de su servicio tenderían a ser API más generales que no están estrechamente vinculadas a una aplicación específica. Sus definiciones de servicio probablemente accederían directamente a las bases de datos a través de JDBC o Hibernate o incluso archivos en el sistema de archivos del servidor. Para muchas aplicaciones, esta vista es apropiada y puede ser muy eficiente porque reduce la cantidad de niveles.

Despliegue multinivel

En arquitecturas de niveles múltiples más complejas, las definiciones de su servicio GWT podrían ser simplemente pasarelas livianas que atraviesan entornos de servidor back-end como servidores J2EE. Desde esta perspectiva, sus servicios se pueden ver como la "mitad del servidor" de la interfaz de usuario de su aplicación. En lugar de ser de propósito general, los servicios se crean para las necesidades específicas de su interfaz de usuario. Sus servicios se convierten en el "front-end" de las clases "back-end" que se escriben al unir llamadas a una capa de servicios back-end más general, implementada, por ejemplo, como un clúster de servidores J2EE. Este tipo de arquitectura es apropiada si requiere que sus servicios de back-end se ejecuten en una computadora físicamente separada de su servidor HTTP ".

También tenga en cuenta que la configuración de un único servicio RequestFactory requiere la creación de alrededor de 6 clases de Java en las que RPC solo requiere 3. Más código == más errores y complejidad en mi libro.

RequestFactory también tiene un poco más de sobrecarga durante el procesamiento de solicitudes, ya que tiene que ordenar la serialización entre los proxies de datos y los modelos reales de Java. Esta interfaz agregada agrega ciclos de procesamiento adicionales que realmente pueden sumarse en una empresa o entorno de producción.

Tampoco creo que los servicios de RequestFactory sean serialización como los servicios de RPC.

Con todo, después de usar ambos desde hace un tiempo, siempre uso RPC porque es más liviano, más fácil de probar y depurar, y más rápido que usar RequestFactory. Aunque RequestFactory podría ser más elegante y extensible, entonces su parte de contador RPC. La complejidad añadida no la hace una mejor herramienta necesaria.

Mi opinión es que la mejor arquitectura es usar dos aplicaciones web, un cliente y un servidor. El servidor es una aplicación web java genérica ligera y sencilla que utiliza la biblioteca servlet.jar. El cliente es GWT. Realiza una solicitud RESTful a través de GWT-RPC en el lado del servidor de la aplicación web del cliente. El lado del servidor del cliente es solo un pase al cliente HTTP apache que usa un túnel persistente en el controlador de solicitudes que tiene funcionando como un servlet único en la aplicación web de servlet del servidor. La aplicación web servlet debe contener su capa de aplicación de base de datos (hibernate, cayenne, sql, etc.). Esto le permite divorciarse por completo de los modelos de objetos de la base de datos del cliente real proporcionando una manera mucho más ampliable y robusta de desarrollar y probar su aplicación. De acuerdo, requiere un poco de tiempo de configuración inicial, pero al final le permite crear una fábrica de solicitudes dinámicas ubicada fuera de GWT. Esto le permite aprovechar lo mejor de ambos mundos. Sin mencionar que puedes probar y hacer cambios a tu lado del servidor sin tener que compilar o construir el cliente gwt.


Creo que es muy útil si tienes un pojo pesado en el lado del cliente, por ejemplo, si usas entidades Hibernate o JPA. Adoptamos otra solución, utilizando un marco de persistencia de estilo Django con entidades muy livianas.


Creo que la idea de crear clases Proxy para todas mis entidades es bastante molesta. Mis pojos de Hibernate / JPA se generan automáticamente a partir del modelo de base de datos. ¿Por qué ahora necesito crear un segundo espejo de esos para RPC? Tenemos un buen marco de "estivación" que se encarga de "deshiburizar" los pojos.

Además, la idea de definir interfaces de servicio que no implementen completamente el servicio del lado del servidor como un contrato de Java pero implementan los métodos, me suena muy J2EE 1.x / 2.x.


La única advertencia que pondría es que RequestFactory usa el transporte de datos binarios (¿deRPC quizás?) Y no el GWT-RPC normal.

Esto solo importa si realiza pruebas exhaustivas con SyncProxy, Jmeter, Fiddler o cualquier herramienta similar que pueda leer / evaluar el contenido de la solicitud / respuesta HTTP (como GWT-RPC), pero sería más difícil con deRPC o RequestFactory.


La gran diferencia entre GWT RPC y RequestFactory es que el sistema RPC es "RPC-por-concreto-tipo" mientras que RequestFactory es "RPC-por-interfaz".

RPC es más conveniente para empezar, porque escribe menos líneas de código y usa la misma clase tanto en el cliente como en el servidor. Puede crear una clase Person con un grupo de getters y setters y tal vez una lógica de negocio simple para cortar y dividir los datos en el objeto Person . Esto funciona bastante bien hasta que terminas queriendo tener un código específico del servidor, no compatible con GWT dentro de tu clase. Debido a que el sistema RPC se basa en tener el mismo tipo de concreto tanto en el cliente como en el servidor, puede alcanzar un muro de complejidad basado en las capacidades de su cliente GWT.

Para evitar el uso de un código incompatible, muchos usuarios terminan creando un PersonDTO igual que sombrea el objeto Person real utilizado en el servidor. El PersonDTO solo tiene un subconjunto de los getters y setters del lado del servidor, "dominio", objeto Person . Ahora debe escribir el código que PersonDTO los datos entre los objetos Person y PersonDTO y todos los demás tipos de objetos que desea pasar al cliente.

RequestFactory comienza asumiendo que los objetos de su dominio no serán compatibles con GWT. Simplemente declara las propiedades que debe leer y escribir el código del cliente en una interfaz Proxy, y los componentes del servidor RequestFactory se encargan de ordenar los datos e invocar sus métodos de servicio. Para las aplicaciones que tienen un concepto bien definido de "Entidades" u "Objetos con identidad y versión", el tipo de EntityProxy se usa para exponer la semántica de identidad persistente de sus datos al código del cliente. Los objetos simples se asignan utilizando el tipo ValueProxy .

Con RequestFactory, paga un costo de inicio inicial para acomodar sistemas más complicados de lo que GWT RPC soporta fácilmente. El ServiceLayer de ServiceLayer proporciona muchos más ganchos para personalizar su comportamiento agregando instancias de ServiceLayerDecorator .


Pasé por una transición de RPC a RF. Primero debo decir que mi experiencia es limitada en eso, utilicé tantos EntityProxies como 0.

Ventajas de GWT RPC:

  • ¡Es muy fácil de configurar, entender y APRENDER!
  • Los mismos objetos basados ​​en clase se usan en el cliente y en el servidor.
  • Este enfoque ahorra toneladas de código.
  • Ideal, cuando se usan los mismos objetos modelo (y POJOS) en el cliente y el servidor, POJOs == MODEL OBJECT == DTOs
  • Fácil de mover cosas del servidor al cliente.
  • Es fácil compartir la implementación de la lógica común entre el cliente y el servidor (esto puede convertirse en una desventaja crítica cuando se necesita una lógica diferente).

Desventajas de GWT RPC:

  • Imposible tener una implementación diferente de algunos métodos para el servidor y el cliente, por ejemplo, puede necesitar usar un marco de trabajo de registro diferente en el cliente y el servidor, o un método de igual diferencia.
  • REALMENTE MALA implementación que no es más ampliable: la mayor parte de la funcionalidad del servidor se implementa como métodos estáticos en una clase RPC. QUE REALMENTE CHUPA.
  • por ejemplo, es imposible agregar ofuscación de errores del lado del servidor
  • Algunos problemas de XSS de seguridad que no son muy fáciles de resolver, consulte los documentos (no estoy seguro de si esto es más elegante para RequestFactory)

Desventajas de RequestFactory:

  • REALMENTE DIFÍCIL de entender del documento oficial, ¿cuál es el mérito de ello? Comienza justo en el término completamente engañoso. PROXIES: estos son en realidad DTO de RF que son creados por RF automáticamente. Los proxies están definidos por interfaces, p. Ej. @ProxyFor (Journal.class). IDE comprueba si existen métodos correspondientes en Journal. Mucho para el mapeo.
  • RF no hará mucho por usted en términos de características comunes de cliente y servidor porque
  • En el cliente debe convertir "PROXIES" a los objetos de dominio de su cliente y viceversa. Esto es completamente ridículo Se podría hacer en pocas líneas de código declarativamente, ¡pero NO HAY APOYO PARA ESO! Si solo pudiéramos asignar nuestros objetos de dominio a proxies de manera más elegante, algo así como el método de JavaScript JSON.stringify (.. ,,) FALTA en la caja de herramientas de RF.
  • No olvide que también es responsable de establecer las propiedades transferibles de los objetos de su dominio en proxies, y así sucesivamente de forma recursiva.
  • POBRE MANEJO DE ERRORES en el servidor y - Las huellas de pila se omiten de manera predeterminada en el servidor y se obtienen excepciones vacías e inútiles en el cliente. Incluso cuando configuré un controlador de errores personalizado, ¡no pude acceder a rastros de pila de bajo nivel! Terrible.
  • Algunos errores menores en el soporte de IDE y en otros lugares. Archivé dos solicitudes de error que fueron aceptadas. No se necesitaba un Einstein para descubrir que esos eran en realidad bichos.
  • LA DOCUMENTACIÓN CHUPA. Como mencioné que los proxies deberían ser mejor explicados, el término es MALIGNO. Para los problemas comunes básicos, que estaba resolviendo, DOCS ES INÚTIL. Otro ejemplo de malentendido del DOC es la conexión de anotaciones JPA a RF. Desde los sucintos documentos se ve que juegan un poco juntos, y sí, hay una pregunta correspondiente en . Recomiendo olvidar cualquier ''conexión'' JPA antes de entender RF.

Ventajas de RequestFactory

  • Excelente soporte de foro
  • El soporte de IDE es bastante bueno (pero no es una ventaja en contraste con RPC)
  • Flexibilidad de la implementación de su cliente y servidor (acoplamiento flexible)
  • Cosas sofisticadas, conectadas a EntityProxies, más allá de DTO simples: almacenamiento en caché, actualizaciones parciales, muy útiles para dispositivos móviles.
  • Puede usar ValueProxies como el reemplazo más simple para los DTO (pero usted mismo tiene que hacer todas las conversiones no tan lujosas).
  • Soporte para Bean Validations JSR-303.

Considerando otras desventajas de GWT en general:

  • Imposible ejecutar pruebas de integración (código de cliente GWT + servidor remoto) con compatibilidad JUnit proporcionada <= todas las JSNI tienen que ser burladas (por ejemplo, localStorage), SOP es un problema.

  • No hay soporte para configuración de prueba: explorador sin cabeza + servidor remoto <= no hay pruebas sin cabeza simples para GWT, SOP.

  • Sí, es posible ejecutar pruebas de integración de selenio (pero eso no es lo que quiero)

  • JSNI es muy poderoso, pero en esas charlas brillantes que dan en las conferencias no hablan mucho de que escribir códigos JSNI también tiene algunas reglas. Una vez más, averiguar cómo escribir una devolución de llamada simple era una tarea que valía la pena de un verdadero investigador.

En resumen, la transición de GWT RPC a RequestFactory está lejos de la situación WIN-WIN, cuando RPC se ajusta principalmente a sus necesidades. Terminas escribiendo toneladas de conversiones de objetos de dominio de cliente a proxies y viceversa. Pero obtienes cierta flexibilidad y solidez de tu solución. ¡Y el apoyo en el foro es excelente, el sábado también!

Teniendo en cuenta todas las ventajas y desventajas que acabo de mencionar, vale la pena pensar de antemano si alguno de estos enfoques mejora su solución y su configuración de desarrollo sin grandes concesiones.


Tenemos una implementación muy grande de GWT-RPC en nuestro proyecto. En realidad, tenemos 50 interfaces de servicio con muchos métodos cada una, y tenemos problemas con el tamaño de los TypeSerializers generados por el compilador que hace que nuestro código JS sea enorme. Entonces estamos analizando para avanzar hacia RequestFactory. Me han leído durante un par de días buscando en la web e intentando encontrar lo que otras personas están haciendo. El inconveniente más importante que vi, y quizás podría estar equivocado, es que con RequestFactory ya no tienes el control de la comunicación entre tus objetos del Dominio del Servidor y tus clientes. Lo que necesitamos es aplicar el patrón de carga / guardado de una manera controlada. Quiero decir, por ejemplo, que el cliente reciba el gráfico de objeto completo de los objetos que pertenecen a una transacción específica, haga sus actualizaciones y los envíe de vuelta al servidor. El servidor será responsable de hacer la validación, comparar valores antiguos con nuevos y hacer persistencia. Si 2 usuarios de diferentes sitios obtienen la misma transacción y realizan algunas actualizaciones, la transacción resultante no debería ser la fusionada. Una de las actualizaciones debería fallar en mi escenario. No veo que RequestFactory ayude a soportar este tipo de procesamiento.

Saludos Daniel