¿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?


Answers

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 .


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


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.


¿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.


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.


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.


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.


He tenido el mismo error y soluciono esto limpiando el caché de navegación y el historial de navegación.