RequestFactoryとGWT-RPCはいつ使用する必要がありますか?


87

gwt-rpc呼び出しを新しいGWT2.1RequestFactorycalに移行する必要があるかどうかを判断しようとしています。

Googleのドキュメントでは、RequestFactoryが「データ指向サービス」のためのより優れたクライアントサーバー通信方法であると漠然と述べています。

ドキュメントから推測できるのは、通信を簡素化する新しいProxyクラスがあるということです(実際のエンティティをやり取りするのではなく、プロキシだけを渡すので、軽量で管理が簡単です)。

それが全体の要点ですか、それとも全体像の中で何か他のものが欠けていますか?


8
ええ、この質問は公式のgwt devguideからリンクされています!
törzsmókus

回答:


73

GWT RPCとRequestFactoryの大きな違いは、RPCシステムが「RPC-by-concrete-type」であるのに対し、RequestFactoryは「RPC-by-interface」であるということです。

RPCは、コードの行数を減らし、クライアントとサーバーの両方で同じクラスを使用するため、使い始めるのに便利です。Personゲッターとセッターの束と、Personオブジェクト内のデータをさらにスライスおよびダイシングするためのいくつかの単純なビジネスロジックを使用してクラスを作成する場合があります。これは、サーバー固有の非GWT互換のコードをクラス内に配置する必要が生じるまでは非常にうまく機能します。RPCシステムは、クライアントとサーバーの両方で同じ具象タイプを持つことに基づいているため、GWTクライアントの機能に基づいて複雑な壁にぶつかる可能性があります。

互換性のないコードの使用を回避するために、多くのユーザーは、サーバーで使用されるPersonDTO実際のPersonオブジェクトをシャドウするピアを作成することになります。PersonDTOただ、サーバー側のゲッターとセッターのサブセット、「ドメイン」、持っているPersonオブジェクトを。次に、PersonPersonDTOオブジェクトと、クライアントに渡す他のすべてのオブジェクトタイプとの間でデータをマーシャルするコードを作成する必要があります。

RequestFactoryは、ドメインオブジェクトがGWT互換ではないと想定することから始めます。プロキシインターフェイスでクライアントコードによって読み書きされるプロパティを宣言するだけで、RequestFactoryサーバーコンポーネントがデータのマーシャリングとサービスメソッドの呼び出しを処理します。「エンティティ」または「IDとバージョンを持つオブジェクト」の明確に定義された概念を持つアプリケーションの場合、EntityProxyタイプは、データの永続的なIDセマンティクスをクライアントコードに公開するために使用されます。単純なオブジェクトは、ValueProxyタイプを使用してマップされます。

RequestFactoryを使用すると、GWTRPCが簡単にサポートするよりも複雑なシステムに対応するための初期費用を支払う必要があります。RequestFactoryServiceLayerは、ServiceLayerDecoratorインスタンスを追加することで動作をカスタマイズするためのフックを大幅に増やしています。


これは、RequestFactoryに切り替えるという私の決定を支持する良い理由です。ありがとう、ボブ!それは理にかなっており、RPCでは多くのグルーコードとそのDTOレイヤー
Dan L)

5
RequestFactoryのもう1つの利点は、まったく同じコードでAndroidとGWTで使用できることです。
パトリック

28

RPCからRFへの移行を経験しました。まず、私の経験は限られていると言わざるを得ません。私は0と同じ数のEntityProxiesを使用しました。

GWT RPCの利点:

  • セットアップ、理解、学習は非常に簡単です。
  • 同じクラスベースのオブジェクトがクライアントとサーバーで使用されます。
  • このアプローチにより、大量のコードが節約されます。
  • 理想的には、同じモデルオブジェクト(およびPOJOS)がクライアントとサーバーのいずれかで使用されている場合、POJO ==モデルオブジェクト== DTO
  • サーバーからクライアントにものを簡単に移動できます。
  • クライアントとサーバー間で共通ロジックの実装を簡単に共有できます(これは、別のロジックが必要な場合に重大な欠点となる可能性があります)。

GWT RPCのデメリット:

  • サーバーとクライアントに対していくつかのメソッドの異なる実装を持つことは不可能です。たとえば、クライアントとサーバーで異なるロギングフレームワークを使用する必要がある場合や、異なる等しいメソッドを使用する必要がある場合があります。
  • これ以上拡張できない本当に悪い実装:サーバー機能のほとんどは、RPCクラスの静的メソッドとして実装されます。それは本当に吸います。
  • 例:サーバー側のエラーの難読化を追加することはできません
  • 完全にエレガントに解決できないセキュリティXSSの懸念事項については、ドキュメントを参照してください(これがRequestFactoryにとってよりエレガントかどうかはわかりません)

RequestFactoryのデメリット:

  • 公式ドキュメントから理解するのは本当に難しいです、それのメ​​リットは何ですか!それは完全に誤解を招く用語PROXIESから始まります-これらは実際にはRFによって自動的に作成されるRFのDTOです。プロキシは、@ ProxyFor(Journal.class)などのインターフェースによって定義されます。IDEは、ジャーナルに対応するメソッドが存在するかどうかを確認します。マッピングについてはこれだけです。
  • RFは、クライアントとサーバーの共通性に関してはあまり役に立ちません。
  • クライアントでは、「プロキシ」をクライアントドメインオブジェクトに、またはその逆に変換する必要があります。これは完全にばかげています。宣言的に数行のコードで実行できますが、そのためのサポートはありません。ドメインオブジェクトをよりエレガントにプロキシにマッピングできれば、JavaScriptメソッドJSON.stringify(.. ,,)のようなものがRFツールボックスにありません。
  • ドメインオブジェクトの転送可能なプロパティをプロキシなどに再帰的に設定する責任もあることを忘れないでください。
  • サーバーでの不十分なエラー処理および-サーバーではスタックトレースがデフォルトで省略され、クライアントで空の不要な例外が発生します。カスタムエラーハンドラーを設定しても、低レベルのスタックトレースに到達できませんでした。ひどい。
  • IDEサポートおよびその他の場所でのいくつかのマイナーなバグ。受け入れられた2つのバグリクエストを提出しました。それらが実際にバグであると理解するためにアインシュタインは必要ありませんでした。
  • ドキュメントは吸います。プロキシについてよりよく説明する必要があると述べたように、この用語は誤解を招くものです。私が解決していた基本的な一般的な問題については、DOCS ISUSELESSです。DOCからの誤解のもう1つの例は、JPAアノテーションのRFへの接続です。簡潔なドキュメントから、彼らはちょっと一緒に遊んでいるように見えます、そしてはい、StackOverflowに対応する質問があります。RFを理解する前に、JPAの「接続」を忘れることをお勧めします。

RequestFactoryの利点

  • 優れたフォーラムサポート。
  • IDEのサポートはかなり良いです(ただし、RPCとは対照的に利点ではありません)
  • クライアントとサーバーの実装の柔軟性(疎結合)
  • 単純なDTOを超えて、EntityProxiesに接続された豪華なもの-キャッシュ、部分的な更新、モバイルに非常に便利です。
  • ValueProxiesをDTOの最も単純な代替として使用できます(ただし、それほど凝った変換を自分で行う必要はありません)。
  • Bean ValidationJSR-303のサポート。

一般的にGWTの他の欠点を考慮する:

  • 提供されたJUnitサポートを使用して統合テスト(GWTクライアントコード+リモートサーバー)を実行することはできません<=すべてのJSNIをモックする必要があります(例:localStorage)。SOPが問題です。

  • セットアップのテストはサポートされていません-ヘッドレスブラウザ+リモートサーバー<= GWT、SOPの単純なヘッドレステストはありません。

  • はい、セレン統合テストを実行することは可能です(しかし、それは私が望んでいることではありません)

  • JSNIは非常に強力ですが、会議で行われるこれらの輝かしい講演では、JSNIコードの記述にはいくつかのルールもあることについてあまり話しません。繰り返しになりますが、簡単なコールバックの書き方を理解することは、真の研究者にとって価値のある作業でした。

要約すると、GWT RPCからRequestFactoryへの移行は、RPCがほとんどニーズに合っている場合、WIN-WINの状況からはほど遠いものです。クライアントドメインオブジェクトからプロキシへ、またはその逆に大量の変換を書き込むことになります。ただし、ソリューションにはある程度の柔軟性と堅牢性があります。そして、フォーラムでのサポートは土曜日にも素晴らしいです!

今述べたすべての長所と短所を考慮すると、これらのアプローチのいずれかが実際にソリューションと開発セットアップに大きなトレードオフなしで改善をもたらすかどうかを事前に考えることは非常に有益です。


JBossEraiをチェックアウトします。私は彼らのRPCへのアプローチが大好きです。
Καrτhικ

6

すべてのエンティティのプロキシクラスを作成するというアイデアは非常に面倒です。私のHibernate / JPA pojoは、データベースモデルから自動生成されます。RPC用にそれらの2番目のミラーを作成する必要があるのはなぜですか?ポジョの「休止状態解除」を処理する優れた「推定」フレームワークがあります。

また、サーバー側サービスをJavaコントラクトとして完全には実装しないが、メソッドを実装するサービスインターフェイスを定義するというアイデアは、私には非常にJ2EE 1.x /2.xのように聞こえます。


5
面倒ですが、とにかくプロキシを作成する必要がある場合は、RFがそれらのプロキシを管理するために提供する追加のヘルプが必要です。誰もがpojo全体をクライアントに送信したいとは限りません(たとえば、ポーカーゲームを考えてみてください)。Playerオブジェクトには、誰もが見るべき情報(手札のカードの数、表向きに表示されているカード、合計チップ)などの情報が含まれている場合があります。 1人のプレイヤーが見る必要があります(裏向きのカード)。
Peter Recore 2011

あなたのポーカーの例は有効です-私たちは「推定」フレームワークが値を抑制するために使用する注釈(@WireTransient)を持つことによってそれを回避します。
Καrτhικ

4

エラー処理およびテスト機能が不十分なRequestFactoryとは異なり(GWTの内部でほとんどのものを処理するため)、RPCではよりサービス指向のアプローチを使用できます。RequestFactoryは、複雑なポリモーフィックデータ構造を呼び出す必要がある場合に役立つアプローチを提供できる、より最新の依存性注入スタイルのアプローチを実装しています。RPCを使用する場合、マーシャリングユーティリティがjson / xmlモデルとjavaモデルの間で変換できるようになるため、データ構造をよりフラットにする必要があります。RPCを使用すると、GoogleのWebサイトのgwt devセクションから引用されているように、より堅牢なアーキテクチャを実装することもできます。

「シンプルなクライアント/サーバー展開

サービス定義を考える最初の最も簡単な方法は、それらをアプリケーションのバックエンド全体として扱うことです。この観点から、クライアント側のコードは「フロントエンド」であり、サーバーで実行されるすべてのサービスコードは「バックエンド」です。このアプローチを採用する場合、サービスの実装は、1つの特定のアプリケーションに緊密に結合されていないより汎用的なAPIになる傾向があります。サービス定義は、JDBCまたはHibernateを介して、あるいはサーバーのファイルシステム内のファイルを介してデータベースに直接アクセスする可能性があります。多くのアプリケーションでは、このビューが適切であり、層の数が減るため、非常に効率的です。

多層展開

より複雑な多層アーキテクチャでは、GWTサービス定義は、J2EEサーバーなどのバックエンドサーバー環境を呼び出す軽量ゲートウェイである可能性があります。この観点から、サービスはアプリケーションのユーザーインターフェイスの「サーバーの半分」と見なすことができます。サービスは、汎用ではなく、ユーザーインターフェイスの特定のニーズに合わせて作成されます。サービスは、たとえばJ2EEサーバーのクラスターとして実装された、より汎用的なサービスのバックエンドレイヤーへの呼び出しをつなぎ合わせることによって作成される「バックエンド」クラスの「フロントエンド」になります。この種のアーキテクチャは、バックエンドサービスをHTTPサーバーとは物理的に別のコンピューターで実行する必要がある場合に適しています。」

また、単一のRequestFactoryサービスを設定するには、約6個程度のJavaクラスを作成する必要がありますが、RPCでは3個しか必要ありません。コードが増える==私の本ではエラーと複雑さが増します。

RequestFactoryは、データプロキシと実際のJavaモデルの間でシリアル化をマーシャリングする必要があるため、要求処理中のオーバーヘッドも少し多くなります。この追加されたインターフェースは、企業または実稼働環境で実際に追加される可能性のある追加の処理サイクルを追加します。

また、RequestFactoryサービスがRPCサービスのようなシリアル化であるとは思いません。

全体として、しばらくの間両方を使用した後、私は常にRPCを使用します。これは、より軽量で、テストとデバッグが簡単で、RequestFactoryを使用するよりも高速です。RequestFactoryは、RPCカウンターパートよりもエレガントで拡張可能かもしれませんが。追加された複雑さは、それを必要とするより良いツールにしません。

私の意見では、最良のアーキテクチャは2つのWebアプリ、1つのクライアントと1つのサーバーを使用することです。サーバーは、servlet.jarライブラリを使用するシンプルで軽量な汎用JavaWebアプリケーションです。クライアントはGWTです。GWT-RPCを介してクライアントWebアプリケーションのサーバー側にRESTfulリクエストを送信します。クライアントのサーバー側は、サーバーサーブレットWebアプリケーションで単一のサーブレットとして実行しているリクエストハンドラーへの永続的なトンネルを使用するApachehttpクライアントへの単なるパススルーです。サーブレットWebアプリケーションには、データベースアプリケーション層(hibernate、cayenne、sqlなど)が含まれている必要があります。これにより、データベースオブジェクトモデルを実際のクライアントから完全に切り離して、アプリケーションを開発およびユニットテストするためのはるかに拡張可能で堅牢な方法を提供できます。確かに、少しの初期セットアップ時間が必要ですが、しかし、最終的には、GWTの外部にある動的リクエストファクトリを作成できます。これにより、両方の長所を活用できます。gwtクライアントをコンパイルまたはビルドしなくても、サーバー側でテストおよび変更を行うことができることは言うまでもありません。


0

HibernateまたはJPAエンティティを使用する場合など、クライアント側に重いpojoがある場合は、非常に役立つと思います。非常に軽いエンティティでDjangoスタイルの永続性フレームワークを使用する別のソリューションを採用しました。


0

私が指摘する唯一の注意点は、RequestFactoryが通常のGWT-RPCではなくバイナリデータトランスポート(deRPCかもしれませんか?)を使用することです。

これは、SyncProxy、Jmeter、Fiddler、またはHTTP要求/応答の内容を読み取り/評価できる同様のツール(GWT-RPCなど)で重いテストを行っている場合にのみ問題になりますが、deRPCまたはRequestFactoryではより困難になります。


1
ただし、実際にはRequestFactoryは、SyncProxyなどのサードパーティツールを必要とせずに、すぐに使用できる「純粋なJava」実装を提供します。stackoverflow.com/questions/4853188/を

0

私たちのプロジェクトには、GWT-RPCの非常に大規模な実装があります。実際には、それぞれ多くのメソッドを持つ50のサービスインターフェイスがあり、コンパイラによって生成されるTypeSerializersのサイズに問題があり、JSコードが巨大になります。そのため、RequestFactoryに移行するために分析しています。私は2、3日間、Webを掘り下げて、他の人が何をしているのかを見つけようと読んでいます。私が見た最も重要な欠点は、おそらく私が間違っている可能性があることですが、RequestFactoryを使用すると、サーバードメインオブジェクトとクライアントオブジェクト間の通信を制御できなくなることです。必要なのは、制御された方法でロード/保存パターンを適用することです。つまり、たとえば、クライアントは特定のトランザクションに属するオブジェクトのオブジェクトグラフ全体を受信し、更新を実行すると、全体がサーバーに返送されます。サーバーは、検証を行い、古い値と新しい値を比較し、永続性を実行する責任があります。異なるサイトの2人のユーザーが同じトランザクションを取得して更新を行った場合、結果のトランザクションはマージされたトランザクションではありません。私のシナリオでは、更新の1つが失敗するはずです。RequestFactoryがこの種の処理のサポートに役立つとは思いません。

よろしくダニエル


私はこれらの懸念を共有します...あなたはRFを使うことになりましたか?
HDave 2011年

0

限定されたMISアプリケーションを検討する場合、たとえば10〜20個のCRUD可能なビジネスオブジェクトがあり、それぞれに1〜10個のプロパティがある場合、どちらのルートを使用するかは個人の好みに依存すると言っても過言ではありませんか?

もしそうなら、おそらくアプリケーションがどのようにスケーリングするかを予測することが、ルートGWTRPCまたはRequestFactoryを選択する際の鍵となる可能性があります。

  1. 私のアプリケーションは、その比較的限られた数のエンティティにとどまることが期待されていますが、それらの数の点では大幅に増加します。10〜20オブジェクト* 100,000レコード。

  2. 私のアプリケーションはエンティティの幅が大幅に増える予定ですが、それぞれに関連する相対的な数は少ないままです。5000オブジェクト* 100レコード。

  3. 私のアプリケーションは、その比較的限られた数のエンティティにとどまり、比較的少数の、たとえば10〜20個のオブジェクト* 100レコードにとどまると予想されます。

私の場合、私はこの決定を下そうとするまさに出発点にいます。UIクライアント側のアーキテクチャを変更し、トランスポートを選択する必要があるため、さらに複雑になります。私の以前の(大幅に)大規模なGWT UIは、GWTMVP機能に取って代わられたHmvc4Gwtライブラリーを使用していました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.