図3●Ajaxの基本的な動き
Ajaxアプリケーションは,WebブラウザではなくJavaScriptがWebサーバーへの接続を指示する。送受信されるデータ形式は,HTMLではなくXMLまたはテキスト形式。呼び出されるサーバー側プログラムは,Webサービスになる

[画像のクリックで拡大表示]

図4●XMLRPCでWebサービスを呼び出す場合の例
クライアントとサーバー間のやり取りはXML形式のデータになる。サービスを呼び出すには,XML形式の引数を作成する必要がある。Webサービスの戻り値から利用者に表示する値などを取得するには,XML形式のデータをパースする必要がある

[画像のクリックで拡大表示]

リスト2●REST形式のWebサービスを呼び出すコードの例
POSTメソッドの場合には,setRequestHeaderの呼び出しが必要

[画像のクリックで拡大表示]

 一般的なWebアプリケーションは利用者の操作を契機にサーバーと通信を開始するが,AjaxはJavaScriptの指示でサーバー側のプログラムを呼び出す(図3[拡大表示])。ページの部分的な変更が可能で,マウスの移動などを契機にプログラムを動作できる。これらにより,Ajaxでは操作性を向上させたり性能を向上させたりすることが可能になる。これが前回説明したAjaxの特徴だ。

 今回と次回は,Ajaxアプリケーションを開発する際の注意点,特にサーバー側のWebサービスにまつわる注意点を取り上げる。

●サーバーとの通信データ
性能重視ならXMLは使わない

 Ajaxのサーバー側プログラムであるWebサービスは,Ajaxクライアントによって何度も呼び出される可能性がある。例えばマウスの動きによって何か処理するのであれば,マウスが動くたびに呼び出される。つまり,Ajaxアプリケーションの処理性能はWebサービスとの通信処理に依存することになる。処理性能を左右するポイントは,通信データ形式にある。

SOAPより軽量なXMLRPC

 一般にWebサービスと言えば,XML形式でデータをやり取りするのが基本である。Webサービスと言えばすぐに思い浮かぶのが「SOAP」だ。しかしSOAPは,SOAPエンベロープ(ヘッダーなどを含むフォーマット)を付けて送受信する必要があり,やや冗長なプロトコルである。AjaxでSOAPを扱うことは可能だが,JavaScriptでSOAPを使おうとすると,開発者がSOAPエンベロープなどの要素を作成する必要があり,プログラムが複雑になる。そのため,Ajaxでの通信にSOAPが使われることはほとんどない*1

 SOAPより少し軽量なプロトコルとして「XMLRPC*2」がある。XMLRPCは,引数や戻り値を,型に応じた簡単なタグでくくって呼び出す方式である。ブログの実装などでよく使われており,ライブラリも充実している。AjaxでXMLRPCのWebサービスを呼び出すには,文字列結合やDOMDocumentオブジェクト(XMLのオブジェクト形式)を使って,引数をXML形式で作成する。その引数をXMLHttpRequestオブジェクト*3のsendメソッドの引数として指定すれば,サーバー側のプログラムが呼び出される(図4[拡大表示])。サーバー側からの戻り値はXML形式になるので,適時パース(解析)処理が必要になる*4

Webサービスの引数にXMLを使わないREST

 XMLRPCはエンベロープなどがない分だけSOAPよりも簡易な方法だが,引数をXML化する処理はなくならず,サーバー側ではXMLのパース処理が必要になる。そこで代案として考えられるのが,引数をテキストのまま送信する「REST方式*5」である。

 REST方式では,GETメソッドのURLクエリー部分(URLの「?」以降)やPOSTメソッドのボディ部に,「引数名=値&引数名=値…」という形式で,引数を渡す。これは,Webアプリケーションが入力フォーム(〈form〉)を使ってSUBMITするときと同じデータ形式である*6。REST方式は呼び出し方法が簡単なので,Ajaxに限らず多くのWebサービスで使われている。

 REST方式の最大の利点は,Webサービスの引数にXML形式を使わない点だ。呼び出し側は,引数を「=」や「&」でつなぎ合わせるだけでよい。呼び出されるサーバー側では,Webアプリケーションのフレームワークが提供する一般的な方法を使って引数を取得できる。例えばPHPなら,「$_GET」や「$_POST」,ASP.NETなら「Requestオブジェクト」といったように,Webアプリケーションのフォームに入力された値を取得するのと同じ方法で引数を得られる。

 またデバッグが容易であるという点も,メリットとして挙げられる。REST方式はWebフォームを使って呼び出すのと同じ形式なので,デバッグ時には,

のようなテスト用のフォームを用意し,それをSUBMITすれば,Webサービスの動作を簡単に調べられる。

 AjaxでREST方式のWebサービスを呼び出すにはリスト2[拡大表示]のように記述する。GETメソッドの場合には,呼び出す際のURLの後ろに,引数をURLクエリーとして指定すればよい。

 POSTメソッドの場合には,sendメソッドでボディ部として引き渡すことになるが,setRequestHeaderを使ってヘッダーのContent-Typeを「application/x-www-form-urlencoded」に設定しておくのがポイントである*7。この設定を忘れると,$_POSTやRequestオブジェクトなどを使って引数を取得できなくなるので注意したい。

JavaScriptのメソッドで展開できるJSON

 REST方式を使うと,Webサービスの引数の引き渡しが簡単になる。残る問題は,Webサービスからの戻り値の形式である。

 もしWebサービスから部分的なHTMLを返し,それを現在表示しているHTMLの特定の要素に流し込むだけなら話は簡単だ。その場合には,戻り値として得たHTML(もしくはXML)を,DOMを使って流し込めばよいだけだからだ。

 そうではなく,Webサービスの戻り値で得た数値や文字列を取り出して加工したい場合,XML形式だとパース処理が必要になる。

 そこで,XMLの代わりに検討したいのが,簡易なテキスト形式としてデータ構造を表現できる「JSON(JavaScript Object Notation)*8」である。JSONは軽量なデータ交換フォーマットであり,JavaScript(ECMA-262)をベースに作られている。JSONの最大の特徴は,JavaScriptの文法を利用しているので,よく使われるevalメソッドを用いて展開できる点だ(図5[拡大表示])*9。JSON形式のデータを読み書きするライブラリは,C,C#,Java,Perl,PHPなど,多数の言語用のものが存在する。そのため,サーバー側でJSON形式の戻り値を生成するのも複雑ではない。

 Ajaxでは,Webサービスとのデータのやり取りをできるだけ簡略化するため,「引数はREST方式で,戻り値はJSON形式で」という構成をとることが多い。しかしこれは一例にすぎず,規則というわけではない。効率面から見れば,引数はREST方式が一般的と思われるが,戻り値をJSON形式にする必然性はない。例えば単純なデータ列なら,カンマ区切りのテキストを返すといった方法でもよいだろう。要は,パースの手間さえなくなればよく,どのような形式が望ましいかは,扱うデータの種類によって違ってくる。

(大澤 文孝 テクニカル・ライター/プログラマ)