Quando dovrei usare RequestFactory rispetto a GWT-RPC?


87

Sto cercando di capire se devo migrare le mie chiamate gwt-rpc al nuovo GWT2.1 RequestFactory cals.

La documentazione di Google menziona vagamente che RequestFactory è un metodo di comunicazione client-server migliore per i "servizi orientati ai dati"

Quello che posso distillare dalla documentazione è che c'è una nuova classe Proxy che semplifica la comunicazione (non si passa avanti e indietro l'entità effettiva ma solo il proxy, quindi è più leggera e più facile da gestire)

È questo il punto o mi manca qualcos'altro nel quadro generale?


8
yay, questa domanda è collegata alla gwt devguide ufficiale !
törzsmókus

Risposte:


73

La grande differenza tra GWT RPC e RequestFactory è che il sistema RPC è "RPC-by-concrete-type" mentre RequestFactory è "RPC-by-interface".

RPC è più comodo per iniziare, perché scrivi meno righe di codice e usi la stessa classe sia sul client che sul server. Potresti creare una Personclasse con un gruppo di getter e setter e magari qualche semplice logica di business per un'ulteriore suddivisione e suddivisione dei dati Personnell'oggetto. Funziona abbastanza bene fino a quando non si finisce per voler avere codice specifico del server, non compatibile con GWT, all'interno della propria classe. Poiché il sistema RPC si basa sull'avere lo stesso tipo concreto sia sul client che sul server, puoi raggiungere un muro di complessità basato sulle capacità del tuo client GWT.

Per aggirare l'uso di codice incompatibile, molti utenti finiscono per creare un peer PersonDTOche oscura l' Personoggetto reale utilizzato sul server. Il PersonDTOsolo ha un sottoinsieme dei getter e setter del server-side, "dominio", Personoggetto. Ora dovete scrivere codice che Marshalls dati tra il Persone PersonDTOoggetto e tutti gli altri tipi di oggetto che si desidera passare al client.

RequestFactory inizia assumendo che i tuoi oggetti di dominio non saranno compatibili con GWT. È sufficiente dichiarare le proprietà che devono essere lette e scritte dal codice client in un'interfaccia proxy e i componenti del server RequestFactory si occupano del marshalling dei dati e del richiamo dei metodi del servizio. Per le applicazioni che hanno un concetto ben definito di "Entità" o "Oggetti con identità e versione", il EntityProxytipo viene utilizzato per esporre la semantica di identità persistente dei dati al codice client. Gli oggetti semplici vengono mappati utilizzando il ValueProxytipo.

Con RequestFactory, paghi un costo iniziale di avvio per ospitare sistemi più complicati di quelli che GWT RPC supporta facilmente. RequestFactory ServiceLayerfornisce molti più hook per personalizzare il suo comportamento aggiungendo ServiceLayerDecoratoristanze.


Questa è una buona ragione per supportare la mia decisione di passare a RequestFactory. Grazie Bob! Ha senso e non capisco perché alcune persone dicano "usa RPC in alcuni casi e RF in altri a seconda delle tue esigenze" perché sembra che con RPC devi scrivere un sacco di codice colla e quel livello DTO
Dan L.

5
Un altro vantaggio per RequestFactory è che può essere utilizzato con Android e GWT con lo stesso identico codice.
Patrick

28

Ho attraversato una transizione da RPC a RF. Per prima cosa devo dire che la mia esperienza è limitata in quanto, ho usato tanti EntityProxies quanto 0.

Vantaggi di GWT RPC:

  • È molto facile da configurare, capire e IMPARARE!
  • Gli stessi oggetti basati sulla classe vengono utilizzati sul client e sul server.
  • Questo approccio consente di risparmiare tonnellate di codice.
  • Ideale, quando gli stessi oggetti del modello (e POJOS) vengono utilizzati su client e server, POJO == MODEL OBJECT == DTO
  • Facile da spostare materiale dal server al client.
  • Facile condividere l'implementazione della logica comune tra client e server (questo può rivelarsi uno svantaggio critico quando è necessaria una logica diversa).

Svantaggi di GWT RPC:

  • Impossibile avere un'implementazione diversa di alcuni metodi per server e client, ad esempio potrebbe essere necessario utilizzare un framework di registrazione diverso su client e server o metodi uguali diversi.
  • Implementazione VERAMENTE CATTIVA che non è ulteriormente estensibile: la maggior parte delle funzionalità del server è implementata come metodi statici su una classe RPC. CHE FA DAVVERO.
  • Ad esempio, è impossibile aggiungere l'offuscamento degli errori lato server
  • Alcuni problemi di sicurezza XSS che non sono risolvibili in modo abbastanza elegante, vedere la documentazione (non sono sicuro che sia più elegante per RequestFactory)

Svantaggi di RequestFactory:

  • DAVVERO DIFFICILE da capire dal documento ufficiale, qual è il merito! Inizia proprio con il termine completamente fuorviante PROXIES: questi sono in realtà DTO di RF che vengono creati automaticamente da RF. I proxy sono definiti dalle interfacce, ad esempio @ProxyFor (Journal.class). IDE controlla se esistono metodi corrispondenti su Journal. Questo per quanto riguarda la mappatura.
  • RF non farà molto per te in termini di punti in comune tra client e server perché
  • Sul client è necessario convertire i "PROXIES" negli oggetti del dominio del client e viceversa. Questo è completamente ridicolo. Potrebbe essere fatto in poche righe di codice in modo dichiarativo, ma NON C'È SUPPORTO PER QUESTO! Se solo potessimo mappare i nostri oggetti di dominio ai proxy in modo più elegante, qualcosa come il metodo JavaScript JSON.stringify (.. ,,) è MANCANTE nella casella degli strumenti RF.
  • Non dimenticare che sei anche responsabile dell'impostazione delle proprietà trasferibili degli oggetti del tuo dominio ai proxy e così via in modo ricorsivo.
  • SCARSA GESTIONE DEGLI ERRORI sul server e - Le tracce di stack vengono omesse per impostazione predefinita sul server e si ottengono eccezioni vuote e inutili sul client. Anche quando ho impostato il gestore degli errori personalizzato, non sono stato in grado di ottenere tracce dello stack di basso livello! Terribile.
  • Alcuni bug minori nel supporto IDE e altrove. Ho presentato due richieste di bug che sono state accettate. Non era necessario un Einstein per capire che si trattava in realtà di insetti.
  • LA DOCUMENTAZIONE FA SCHIFO. Come ho già detto, i proxy dovrebbero essere meglio spiegati, il termine è INGANNO. Per i problemi comuni di base, che stavo risolvendo, DOCS È INUTILE. Un altro esempio di incomprensione del DOC è il collegamento delle annotazioni JPA alla RF. Dai documenti succinti sembra che suonino insieme, e sì, c'è una domanda corrispondente su StackOverflow. Consiglio di dimenticare qualsiasi "connessione" JPA prima di comprendere la RF.

Vantaggi di RequestFactory

  • Eccellente supporto per forum.
  • Il supporto IDE è abbastanza buono (ma non è un vantaggio in contrasto con RPC)
  • Flessibilità dell'implementazione del client e del server (accoppiamento libero)
  • Cose fantasiose, connesse a EntityProxies, oltre ai semplici DTO: memorizzazione nella cache, aggiornamenti parziali, molto utili per i dispositivi mobili.
  • Puoi utilizzare ValueProxies come sostituto più semplice dei DTO (ma devi fare tu stesso tutte le conversioni non così fantasiose).
  • Supporto per Bean Validations JSR-303.

Considerando altri svantaggi di GWT in generale:

  • Impossibile eseguire test di integrazione (codice client GWT + server remoto) con il supporto JUnit fornito <= tutto JSNI deve essere deriso (ad esempio localStorage), SOP è un problema.

  • Nessun supporto per la configurazione dei test: browser headless + server remoto <= nessun semplice test headless per GWT, SOP.

  • Sì, è possibile eseguire test di integrazione del selenio (ma non è quello che voglio)

  • JSNI è molto potente, ma in quei discorsi brillanti che danno alle conferenze non parlano molto del fatto che scrivere codici JSNI ha alcune anche alcune regole. Ancora una volta, capire come scrivere un semplice callback era un compito degno di un vero ricercatore.

In sintesi, la transizione da GWT RPC a RequestFactory è lontana dalla situazione WIN-WIN, quando RPC si adatta principalmente alle tue esigenze. Finisci per scrivere tonnellate di conversioni da oggetti di dominio client a proxy e viceversa. Ma ottieni una certa flessibilità e robustezza della tua soluzione. E il supporto sul forum è eccellente, anche sabato!

Considerando tutti i vantaggi e gli svantaggi che ho appena menzionato, vale davvero la pena di pensare in anticipo se uno qualsiasi di questi approcci apporti effettivamente miglioramenti alla tua soluzione e alla tua configurazione di sviluppo senza grandi compromessi.


Checkout JBoss Erai. Adoro il loro approccio a RPC.
Καrτhικ

6

Trovo piuttosto fastidiosa l'idea di creare classi Proxy per tutte le mie entità. I miei pojo Hibernate / JPA vengono generati automaticamente dal modello di database. Perché ora devo creare un secondo mirror di quelli per RPC? Abbiamo un bel quadro "estivazione" che si occupa di "de-ibernare" i pojo.

Inoltre, l'idea di definire interfacce di servizio che non implementano del tutto il servizio lato server come un contratto Java ma implementano i metodi - mi suona molto J2EE 1.x / 2.x.


5
È fastidioso, ma se devi comunque creare proxy, preferiresti avere l'aiuto extra che RF ti dà per la gestione di quei proxy. Non tutti vogliono inviare l'intero pojo al client - ad esempio, considera un gioco di poker - il tuo oggetto Player potrebbe contenere informazioni che tutti dovrebbero vedere (numero di carte in mano, carte scoperte, chip totali) e altre informazioni che solo un giocatore dovrebbe vedere (carte coperte).
Peter Recore

Il tuo esempio di poker è valido - lavoriamo attorno a questo avendo annotazioni (@WireTransient) che il nostro framework di "estivazione" utilizza per sopprimere i valori.
Καrτhικ

4

A differenza di RequestFactory che ha scarse capacità di gestione degli errori e di test (poiché elabora la maggior parte delle cose sotto il cofano di GWT), RPC consente di utilizzare un approccio più orientato ai servizi. RequestFactory implementa un approccio in stile di inserimento delle dipendenze più moderno che può fornire un approccio utile se è necessario richiamare strutture di dati polimorfiche complesse. Quando si utilizza RPC, le strutture dei dati dovranno essere più piatte, poiché ciò consentirà alle utilità di marshalling di tradurre tra i modelli json / xml e java. L'utilizzo di RPC consente anche di implementare un'architettura più robusta, come citato dalla sezione gwt dev sul sito Web di Google.

"Distribuzione semplice client / server

Il primo e più semplice modo per pensare alle definizioni dei servizi è trattarle come l'intero back-end dell'applicazione. Da questo punto di vista, il codice lato client è il tuo "front-end" e tutto il codice di servizio che viene eseguito sul server è "back-end". Se si adotta questo approccio, le implementazioni del servizio tenderebbero ad essere API più generiche che non sono strettamente collegate a un'applicazione specifica. È probabile che le definizioni dei servizi accedano direttamente ai database tramite JDBC o Hibernate o persino ai file nel file system del server. Per molte applicazioni, questa visualizzazione è appropriata e può essere molto efficiente perché riduce il numero di livelli.

Distribuzione multilivello

In architetture più complesse e multilivello, le definizioni dei servizi GWT potrebbero essere semplicemente gateway leggeri che chiamano attraverso ambienti server back-end come i server J2EE. Da questa prospettiva, i tuoi servizi possono essere visti come la "metà server" dell'interfaccia utente della tua applicazione. Invece di essere generici, i servizi vengono creati per le esigenze specifiche della tua interfaccia utente. I tuoi servizi diventano il "front-end" delle classi "back-end" che vengono scritte unendo le chiamate a un livello di servizi back-end più generico, implementato, ad esempio, come un cluster di server J2EE. Questo tipo di architettura è appropriato se si richiede che i servizi di back-end vengano eseguiti su un computer fisicamente separato dal server HTTP. "

Si noti inoltre che l'impostazione di un singolo servizio RequestFactory richiede la creazione di circa 6 classi java, dove come RPC ne richiede solo 3. Più codice == più errori e complessità nel mio libro.

RequestFactory ha anche un po 'più di overhead durante l'elaborazione della richiesta, in quanto deve effettuare il marshalling della serializzazione tra i proxy di dati e gli effettivi modelli java. Questa interfaccia aggiunta aggiunge cicli di elaborazione extra che possono davvero sommarsi in un ambiente aziendale o di produzione.

Inoltre, non credo che i servizi di RequestFactory siano serializzazione come i servizi RPC.

Tutto sommato, dopo aver usato entrambi per un po 'di tempo, scelgo sempre RPC perché è più leggero, più facile da testare ed eseguire il debug e più veloce rispetto all'utilizzo di RequestFactory. Sebbene RequestFactory potrebbe essere più elegante ed estensibile della sua controparte RPC. La complessità aggiunta non lo rende uno strumento migliore necessario.

La mia opinione è che l'architettura migliore sia quella di utilizzare due app Web, un client e un server. Il server è una semplice webapp java generica e leggera che utilizza la libreria servlet.jar. Il cliente è GWT. Si effettua una richiesta RESTful tramite GWT-RPC nel lato server dell'applicazione web client. Il lato server del client è solo un passaggio al client http di apache che utilizza un tunnel persistente nel gestore delle richieste che hai in esecuzione come un singolo servlet nell'applicazione web del servlet del server. L'applicazione web servlet dovrebbe contenere il livello dell'applicazione database (ibernazione, cayenne, sql ecc.) Ciò consente di separare completamente i modelli di oggetti del database dal client effettivo fornendo un modo molto più estensibile e robusto per sviluppare e testare la propria applicazione. Certo, richiede un po 'di tempo di configurazione iniziale, ma alla fine ti consente di creare una fabbrica di richieste dinamica che si trova al di fuori di GWT. Ciò ti consente di sfruttare il meglio di entrambi i mondi. Per non parlare della possibilità di testare e apportare modifiche al lato server senza dover compilare o compilare il client gwt.


0

Penso che sia davvero utile se hai un pojo pesante sul lato client, ad esempio se usi entità Hibernate o JPA. Abbiamo adottato un'altra soluzione, utilizzando un framework di persistenza in stile Django con entità molto leggere.


0

L'unico avvertimento che vorrei mettere è che RequestFactory utilizza il trasporto binario dei dati (deRPC forse?) E non il normale GWT-RPC.

Questo è importante solo se stai eseguendo test pesanti con SyncProxy, Jmeter, Fiddler o qualsiasi strumento simile in grado di leggere / valutare il contenuto della richiesta / risposta HTTP (come GWT-RPC), ma sarebbe più difficile con deRPC o RequestFactory.


1
Tranne che in realtà RequestFactory fornisce un'implementazione "pura Java" pronta all'uso, senza la necessità di strumenti di terze parti come SyncProxy. Vedi stackoverflow.com/questions/4853188/…
Thomas Broyer

0

Abbiamo un'implementazione molto ampia di GWT-RPC nel nostro progetto. Attualmente abbiamo 50 interfacce di servizio con molti metodi ciascuna, e abbiamo problemi con la dimensione dei TypeSerializer generati dal compilatore che trasforma il nostro codice JS enorme. Quindi stiamo analizzando per passare a RequestFactory. Sono stato letto per un paio di giorni scavando nel web e cercando di scoprire cosa stanno facendo gli altri. Lo svantaggio più importante che ho visto, e forse potrei sbagliarmi, è che con RequestFactory non hai più il controllo della comunicazione tra i tuoi oggetti Dominio Server e quelli client. Ciò di cui abbiamo bisogno è applicare il modello di caricamento / salvataggio in modo controllato. Voglio dire, ad esempio, il client riceve l'intero oggetto grafico degli oggetti appartenenti a una specifica transazione, esegue i suoi aggiornamenti e li rimanda l'intero al server. Il server sarà responsabile della convalida, del confronto dei vecchi con i nuovi valori e della persistenza. Se 2 utenti di siti diversi ottengono la stessa transazione e eseguono alcuni aggiornamenti, la transazione risultante non dovrebbe essere quella unita. Uno degli aggiornamenti dovrebbe fallire nel mio scenario. Non vedo che RequestFactory aiuti a supportare questo tipo di elaborazione.

Saluti Daniel


Condivido queste preoccupazioni ... sei finito con la RF?
HDave

0

È corretto affermare che quando si considera un'applicazione MIS limitata, diciamo con 10-20 oggetti di business CRUD, e ciascuno con ~ 1-10 proprietà, dipende davvero dalle preferenze personali quale percorso seguire?

In tal caso, forse proiettare la scalabilità della tua applicazione potrebbe essere la chiave nella scelta del percorso GWT RPC o RequestFactory:

  1. La mia domanda dovrebbe rimanere con quel numero relativamente limitato di entità, ma aumenterà notevolmente in termini di numero. 10-20 oggetti * 100.000 record.

  2. La mia domanda aumenterà in modo significativo nell'ampiezza delle entità, ma il numero relativo coinvolto di ciascuna rimarrà basso. 5000 oggetti * 100 record.

  3. La mia applicazione dovrebbe rimanere con quel numero relativamente limitato di entità E rimarrà in un numero relativamente basso di ad esempio 10-20 oggetti * 100 record

Nel mio caso, sono proprio all'inizio del tentativo di prendere questa decisione. Ulteriormente complicato dalla necessità di modificare l'architettura lato client dell'interfaccia utente e di effettuare la scelta del trasporto. La mia precedente interfaccia utente GWT (significativamente) su larga scala utilizzava la libreria Hmvc4Gwt, che è stata sostituita dalle strutture GWT MVP.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.