Ext Directはクライアント側においてサーバー側の言語に依存せずにサーバー側のメソッドを遠隔操作するためのプラットフォームであり、技術仕様でもあります。またそれだけではなく、Ext Directを利用したクライアント側のExtアプリケーションであれば、任意のサーバープログラムとの間で通信を行うことが可能です。すでに多くのサーバー側環境とのインテグレーションのためのインターフェースが実装されています:
Ext Directの技術仕様には様々な機能が含まれています。それらを実際に実装する、あるいはしないというのはサーバー側のインターフェースを実装する開発者が判断できるようになっています。いくつかの機能についてはある言語/フレームワークでは実装する必要がないかもしれませんし、逆に言語的に実装ができない機能もあるかもしれません。
サーバ側スタックではメソッドの遠隔操作を可能とするための以下の3つのキーコンポーネントの実装が必須となります。
クライアント側に対してどのクラスをを公開するのか、ということをサーバー側が通知する手段としては通常次の4通りが考えられます:プログラム的に、JSONまたXMLによるコンフィグ、あるいはメタデータ。
プログラム実行時に動的なイントロスペクションが可能な言語であれば公開するメソッドについてより少ないコンフィグ情報ですむことになります。
言語依存の検討事項:
サーバー側のメソッドをコンフィグに記述するための方法は言語によって異なってきます。ある言語で機能したコンフィグが、別の言語では情報不足となってしまう可能性も当然考えられます。コンフィグでは必ず、遠隔操作可能なメソッドがどれなのか、それらの引数は何か、そしてどうやって実行するか、ということを出力する必要があります
プログラム的なコンフィグとは、その言語における「キー/バリュー」のペアによるコンフィグを作るだけのことです。「キー/バリュー」のデータ構造については色々な呼び方があります(ハッシュマップ、辞書、連想配列、構造体、オブジェクトなど)ので、利用されるサーバー側言語で一番利用されている呼び方を使ってください。
上記例では、サーバー側に対して、AlbumListクラスのgetAllとaddの2つのメソッドを公開するようにコンフィグを行っています。getAllメソッドは引数を取らず、addメソッドは引数を1つだけ取ります。上記のようにPHPで実装した場合、引数の名前や型、あるいは引数の順番のような追加の情報について記述する必要はありませんが、他の言語では、こういった追加情報も必要となるかもしれません。その場合、そのような情報もコンフィグの中に記述する必要があります。
上記のコンフィグ情報についてはJSONあるいはXML形式でコンフィグファイルに記述しておき、実行時に読み出させることも可能です。
実行時にメソッドを動的にイントロスペクションできるようなサーバー側の言語を利用する場合はもっと少ない情報でも十分かもしれません。下記のColdFusionのコンポーネントをご覧ください。遠隔操作を可能にするためのExtDirect属性が付与されています。
ColdFusionのExt.Directスタックはこのコンポーネントに対してイントロスペクションを行い、ExtDirect属性を介してこのコンポーネントを遠隔操作可能にするために必要な全ての情報決定することができます。
Ext.DirectスタックにおけるAPIコンポーネントの役割は、Ext.Directがクライアント側においてスタブを生成するために必要なメソッドのコンフィグを出力することです。このような代理のメソッドを生成することにより、クライアントとサーバー間のやり取りを気にせずに、サーバー側のメソッドをあたかもクライアント側のメソッドであるかのように呼び出すことが可能になります。
APIコンポーネントはアプリケーションのヘッド部分においてスクリプトタグ経由で読み込まれます。サーバー側は、クライアント側で実行可能なJavaScriptコードを動的に出力する必要があります。
APIの出力はコンフィグで公開されたメソッドをJavaScriptコードで記述したものになります。下記の例ではExt.app.REMOTING_APIという変数名を使っています。出力内容には、メソッドにアクセスするためのURL、タイプ、そして利用可能なアクション(クラスとメソッド)が含まれます。
ルーターはクライアント側からのリクエストを受け付け、それを適切なクラス、メソッドに引数とともに渡します。
リクエストの送信方法は2つあります:JSONでエンコードされた生のHTTP POSTかformによるPOSTです。ファイルをアップロードする際にはformによるPOSTが必要です。
ルーターは生のHTTP POSTをデコードする必要があります。HTTP POSTが配列で渡ってきた場合、ルーターは複数のリクエストをそれぞれのリクエスト先に配信することになります。
トランザクションが無事受け付けられたら、ルータによってディスパッチされることになります。ルーターは関連するクラスを構築し、受信したデータから読み込んだ引数をもとにメソッドを呼び出します。現時点のExt.Directでは、この引数は配列であることを想定した仕様となっていますが、将来的にはオブジェクトリテラル的なキー/バリュー型の引数をサポートする予定です。
注意 現時点においては、引数をもとにクラスを構築する仕組みは用意されていません。デフォルトのコンストラクターが利用されます。
各トランザクションはその結果を下記の情報を含むキー/バリュー型のデータ構造で返す必要があります。
レスポンスはJSONでエンコードされます。ルーターは複数のトランザクションを1つのレスポンス(配列)にまとめて返すことができます。
リクエストがForm POSTで、そしてアップロードであった場合、レスポンスは下記のようなHTMLとして返すことになります:
<html><body><textarea>{JSONでのレスポンスをここに}</textarea></body></html>
" はバックスラッシュでエスケープしておく必要があります。エスケープしておかないとtextareaの中において実際のクオーテーションマークに変換されてしまうことになります。つまり、次の正規表現をつかうことになります (/"/, "\"")
レスポンスはJSONでエンコードされ、textareaの中に内包されることになります
Form POSTにおいては1回のリクエストでよびだせるメソッドは1つだけです。複数のリクエストをバッチ処理することはできません。
サーバー側において例外が発生した場合、ルーターはそのデバッグモードにおいて以下の情報を返す必要があります。
このルーターにおける例外処理機能については、機能そのものをオン・オフできるようにしておく必要があります。セキュリティ的な観点から、本番環境においてはこれらの例外情報はクライアント側に渡らないようにしておく必要があるからです。
ここでの「例外」はあくまでもサーバー側での例外であり、アプリケーションレベルでのエラーのことではありません。
クライアント側においてExt.Directを利用するためには、APIにおいて使った変数名をプロバイダーとして登録する必要があります
プロバイダーの登録後全てのアクションはグローバルスコープで利用可能となります(APIに名前空間の設定を含めることによりアクションを特定の名前空間に閉じ込めることも可能です)
この時点でクライアント側では、公開されているメソッドをあたかもクライアント側のメソッドであるかのように呼び出せるようになります。
メソッドを呼び出す際にはメソッドが想定する引数に加えて、もう1つコールバック処理用の引数が最後に追加されることになります。これらのサーバー側のメソッドはすべて非同期で処理されることになるため、メソッドのレスポンスを処理する為にはコールバック処理が必要となってくるわけです。メソッド呼び出しのレスポンスはすぐには帰ってきません。
つまり、下記のような書き方はできません:
上記のコードは下記のように書きなおす必要があります: