web-dev-qa-db-ja.com

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

Gwt-rpc呼び出しを新しいGWT2.1 RequestFactory calsに移行する必要があるかどうかを把握しようとしています。

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

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

それが全体のポイントですか、それとも全体像に何か他のものが欠けていますか?

87
Daghan ---

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

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

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

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

RequestFactoryを使用すると、GWT RPCで簡単にサポートできるより複雑なシステムに対応するために、初期費用を支払う必要があります。 RequestFactoryのServiceLayerは、 ServiceLayerDecorator インスタンスを追加することにより、その動作をカスタマイズするための非常に多くのフックを提供します。

73
BobV

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

GWT RPCの利点:

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

GWT RPCの欠点:

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

RequestFactoryの欠点:

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

RequestFactoryの利点

  • 優れたフォーラムサポート。
  • IDEのサポートは非​​常に優れています(ただし、RPCと比較して利点はありません)
  • クライアントとサーバーの実装の柔軟性(疎結合)
  • キャッシング、部分更新、モバイルに非常に役立つ-EntityProxiesに接続された、シンプルなDTOを超えた派手なもの。
  • ValueProxiesをDTOの最も単純な代替品として使用できます(ただし、それほど洗練されていない変換はすべて自分で行う必要があります)。
  • Bean Validations JSR-303のサポート。

一般的なGWTのその他の欠点を考慮すると:

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

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

  • はい、Selenium統合テストを実行できます(しかし、それは私が望むものではありません)

  • JSNIは非常に強力ですが、会議で行われる光沢のある講演では、JSNIコードの作成にはいくつかの規則があることについてはあまり話しません。繰り返しますが、単純なコールバックを記述する方法を見つけることは、真の研究者にとって価値のある作業でした。

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

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

28
honzajde

すべてのエンティティに対してProxyクラスを作成するという考えは非常に面倒です。私のHibernate/JPA pojoは、データベースモデルから自動生成されます。 RPC用に2つ目のミラーを作成する必要があるのはなぜですか?ポジョを「冬眠解除」するニースの「刺激」フレームワークがあります。

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

6
Καrτhικ

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

「単純なクライアント/サーバー展開

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

多層展開

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

また、単一のRequestFactoryサービスを設定するには、RPCが3のみを必要とするクラスを約6個ほど作成する必要があることに注意してくださいJava.

RequestFactoryには、データプロキシと実際のJavaモデルの間のシリアル化をマーシャリングする必要があるため、リクエスト処理中のオーバーヘッドがもう少しあります。エンタープライズ環境または実稼働環境。

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

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

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

4
1-14x0r

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

0
Uberto

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

ダニエルよろしく

0
Daniel Ardison

10〜20のCRUD可能なビジネスオブジェクトと、それぞれ1〜10のプロパティを持つ限られたMISアプリケーションを検討する場合、実際にはどちらのルートを使用するかは個人的な好みに依存すると言うのは公平でしょうか。

もしそうなら、おそらくあなたのアプリケーションがどのようにスケーリングするかを予測することが、あなたのルートGWT RPCまたはRequestFactoryを選択する際の鍵になるでしょう:

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

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

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

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

0
chillyspoon

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

これは、SyncProxy、Jmeter、Fiddler、またはHTTPリクエスト/レスポンス(GWT-RPCなど)のコンテンツを読み取り/評価できる同様のツールで重いテストを行っている場合にのみ重要ですが、deRPCまたはRequestFactoryではさらに困難になります。

0
dhartford