レベル: 中級 Eran Chinthaka (chinthaka@apache.org), PMC Member, Lanka Software Foundation
2007年 5月 24日 リモートでホストされるリソースと対話動作するクライアントにとって、REST (REpresentational State Transfer) が急速に Web サービスを置き換えるものになりつつあります。その大きな理由は、REST ではユーザーが SOAP を理解して使用する必要がないためです。今日の対話性の高い環境にはどちらがより適しているのかに関して、議論が続いています。しかし最近では、WSDL (Web Services Description Language) 2.0 などにも見られるように、Web サービスでも REST の利点を活用できるよう、また REST の概念を利用できるようにする努力がなされています。WSDL 2.0 の付属の仕様としての HTTP バインディング仕様には、これについて多くが記述されています。このシリーズの第 1 回である今回は、WSDL 2.0 では REST と Web サービスとがどのように結びつけられているかに焦点を当てます。そして第 2 回では、これが Apache Web サービス・プロジェクトではどのように実装されているかを説明します。
REST とは何か
Roy T. Fielding は彼の論文「Architectural Styles and the Design of Network-based Software Architectures」(「参考文献」にリンクがあります) の中で、REST を次のように説明しています。
「Representational State Transfer は、しっかりと設計された Web アプリケーションが動作する様子のイメージを想起させようとしています。つまり Web ページのネットワーク (仮想的なステート・マシン) があり、そこではユーザーがリンク (状態遷移) を選択することでアプリケーションの中を進み、その結果ユーザーには次のページ (アプリケーションの、次の状態を表します) が転送され、ユーザーが利用できるように描画されます。」
つまり簡単に言えば、REST はネットワーク・システムのためのアーキテクチャー・スタイルです。では REST とはどんなものなのか、簡単に説明しましょう。
皆さんが Web 検索を行う場合、どのような検索でも実際に皆さんが行っていることは、さまざまな成果物、つまりリソースを探すということがすべてです。ブラウザーに http://ws.apache.org/axis2 と入力して Apache Axis2 の Web サイトまでナビゲートすると、皆さんはサーバー上にある HTML リソースを取得します。言い換えると、そのサーバー上にある、リソースの表現を取得します。このリソース表現は、リソースにアクセスする皆さんを、ある状態にします。皆さんがそのページのリンクをクリックすると、別のリソースの表現を取得します。そうすると、クライアント (つまり皆さん) の状態が変わります。つまり皆さんは状態遷移を経験します。リンクをたどって、さまざまなリソースにアクセスし続けると、皆さんは状態の変化をし続けることになります。REST が意味していることを簡単な言葉で説明すると、以上のようになります。
重要な点として、REST 自体を標準として考えることはできないことに注意してください。
SOAP とは何か
REST が何を意味するのかを理解したら、今度は SOAP とは何かを簡単に復習しましょう。SOAP は (Simple Object Access Protocol の略であるにもかかわらず、もはや単純ではなくなりましたが)、XML をベースに定義されたメッセージング・プロトコルです。メッセージを交換し合う 2 つのエンティティーは、データを SOAP メッセージとして交換することができます (SOAP は言語に依存しないため、どちらのエンティティーも SOAP メッセージを理解することができます)。では典型的な SOAP メッセージを見てみましょう。
リスト 1. SOAP メッセージの例
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<soapenv:Header>
<wsa:MessageID>
uuid:920C5190-0B8F-11D9-8CED-F22EDEEBF7E5</wsa:MessageID>
<wsa:To>
http://localhost:8081/axis/services/BankPort</wsa:To>
</soapenv:Header>
<soapenv:Body>
<axis2:echo xmlns:axis2="http://ws.apache.org/axis2">Hello World </axis2:echo>
</soapenv:Body>
</soapenv:Envelope>
|
SOAP メッセージには、必須の Body 要素とオプションの Header 要素をカプセル化する、Envelope 要素が含まれています。Body 要素に、アプリケーションに送信される、すべての情報が含まれています。Header は主に、WS-Addressing や WS-Security、WS-ReliableMessaging などの QoS (quality of service) を提供するために使われます。
REST 対 Web サービス
今度は、SOAP と REST の主な違いをいくつか見てみましょう。
- REST はリソース指向ですが、Web サービス (WS) はサービス指向です。
- REST はトランスポートとして主に HTTP を使いますが、SOAP はトランスポートの手段に関して特に制限がありません。多くの人は、HTTP を利用して REST スタイルの対話動作を使っています。
- REST を使う場合には、トランスポート自体がすべての QoS パラメーターを提供する必要があります。WS では、QoS オプションをサポートするための多くの仕様が、WS-* 仕様を使って作られています。
どちらのモデルにも強みと弱みがあり、場合によると、それらが補完し合うこともあります。REST は常に単純化を追求し続けているため、新たな WS-* 仕様を定義する人達が単純化を再検討しようとする際の一種の負担になっています。
WSDL 2.0 は、どのように REST と Web サービスとの結合を実現したか
WSDL 2.0 の HTTP バインディング仕様には、REST と Web サービス結びつけるための、あらゆるルールが提供されています。しかし注目に値するのは、REST の意味について、さまざまな人がさまざまな観点を持っているにもかかわらず、この 2 つを結びつける目的が、POX (plain old XML) が基本的な HTTP 操作 (GET や POST、PUT、DELETE など) を用いたサービスと対話動作をできるようにすることである点です。
また、REST のすべてを完全にサポートすることがここでの目的ではないことも、重要な点として覚えておく必要があります。この記事では、Web サービスとして公開されるサービスが、どのようにして REST スタイルの対話動作によって公開され、アクセスされるかについて説明します。また、(あるスタイルの) XML Schema から GET/POST リクエストを作り出す方法を定義します。
HTTP バインディングのための WSDL 2.0 ルール
すべての Web サービスが、さまざまな HTTP メソッドのすべてを備えたサービスとして公開できるわけではありません。こうした制約は、HTTP バインディング仕様で定義されます。
まず、あるサービスで HTTP バインディングを使用できるのかどうかを明らかにする方法を探りましょう。WSDL 2.0 の HTTP バインディング仕様によれば、HTTP バインディングは、<Binding>の type 属性の値を http://www.w3.org/2006/01/wsdl/http に設定することで定義することができます。
リスト 2. HTTP バインディングを持つ WSDL バインディング要素
<description>
<binding name="xs:NCName" interface="xs:QName"?
type="http://www.w3.org/2006/01/wsdl/http"
.....................
..................... />
|
交換するメッセージを作成する際には、シリアライズ機構の違いに十分注意する必要があります。その前に、HTTP メソッドで利用可能なさまざまなコンテンツ・タイプを理解する必要があります。ここではとりあえず、POST メソッドと GET メソッドに焦点を絞りましょう。
表 1. HTTP メソッドでサポートされているコンテンツ・タイプ
| HTTP メソッド | サポートされているコンテンツ・タイプ |
|---|
| GET | すべてのパラメーターは、リクエスト URI (Uniform Resource Identifier) として受信されます。メッセージのスキーマは、IRI (Internationalized Resource Identifier) スタイルに従う必要があります。 |
|---|
| POST |
- すべてのパラメーター、あるいは一部のパラメーターは、URI として受信されます。メッセージのスキーマは IRI スタイルに従う必要があります。
-
application/x-www-form-urlencoded — 一部のパラメーターはリクエスト URI として受信され、一部のパラメーターはメッセージのボディーとして受信されます。メッセージのスキーマは IRI スタイルに従う必要があります。
-
application/xml — XML ペイロードは POST リクエストのボディーの中に含まれます。コンテンツのスキーマに対する制約はありません。
POST メソッドでは、この他のコンテンツ・タイプの大部分がサポートされています。
|
|---|
メッセージのコンテンツとペイロードは、MessageReference あるいは InterfaceFault のいずれかの中で定義されます。これらの要素は、スキーマの中にある要素を必ず参照します。上の表にもあるように、コンテンツ・タイプによって XML ペイロードのスキーマに制約があります。今度は IRI スタイルとは何かを理解しましょう。
Internationalized Resource Identifier スタイル
GET メソッドを使ってサービスと通信しようとする場合、IRI スタイルは、ペイロードのスキーマに対して定義される、いくつかの制約を含んでいます。IRI スタイルは WSDL 2.0 仕様の付属として定義されています。これらの制約を見てみましょう。
- 文書要素のコンテンツ・モデルは、XML Schema からのシーケンスを含む複合型を使って定義する必要があります。
- このシーケンスは、要素のみを含む必要があります。他の構造 (例えば
xs:choice など) を含むことはできません。
- このシーケンスは、ローカルの子要素のみを含む必要があります。これらの子要素は nillable 属性を含む可能性があります。
-
文書要素の
QName の localPart は、オペレーションの名前と同じである必要があります。
- 要素、あるいはその子要素のボディーを定義する複合型は、属性を含むことはできません。
-
シーケンスの子要素が XML Schema 型を使って定義されている場合、それらの要素は
xs:simpleType から派生したものである必要があり、xs:QName や xs:NOTATION、xs:hexBinary、あるいは xs:base64Binary などの型であったり、これらから派生したものであったりしてはいけません。
IRI スタイルによって、リクエスト URI を使って送信されるパラメーターが問題なく妥当な XML に逆変換されることが保証されます。これを理解するには、例を見るのが最も簡単です。
ユーザーの名前と年齢のみを使ってユーザー情報を取得してみましょう。そのためには、サービスに対してリスト 3 の情報を送信する必要があります。
リスト 3. ユーザー情報の例
<GetInformation>
<Name>MyName </Name>
<Age>22 </Age>
</GetInformation>
|
サービスの呼び出しに GET メソッドを使っている場合、これをどのようにリクエスト URI 自体の中に入れてサービスに送信すればよいのでしょう。
その答えは、http://myserver/PersonInfoService/GetInformation?Name=MyName&Age=22 です。
上記にもあるように、IRI スタイルは、XML サンプルを定義するようにスキーマを制限します。これは、GET メソッドを使って複雑な XML を送ることはできないためです。もし Person 要素が、別のサブ要素である Address 要素 (Address 要素は、さらに City 要素と Country 要素を持ちます) を持っていたとすると、複雑なルールを定義しない限り、この要素をリクエスト・パラメーターにシリアライズすることはできません。
WSDL で HTTP バインディングを定義する
今度は、HTTP バインディングを Web サービスのオペレーションに対して定義する方法を見てみましょう。
リスト 4. WSDL バインディング操作
<description>
<binding whttp:methodDefault="xs:string"?
whttp:queryParameterSeparatorDefault="xs:string"?>
<operation ref="xs:QName"
whttp:location="xs:anyURI"?
whttp:method="xs:string"?
whttp:inputSerialization="xs:string"?
whttp:outputSerialization="xs:string"?
whttp:faultSerialization="xs:string"?
whttp:queryParameterSeparator="xs:string"?>
</operation>
</binding>
</description>
|
HTTP バインディング・エクステンションは、一般的なケースに対して明示的に宣言しなければならないものを最小限にとどめるように設計されています。例を見るとわかるとおり、これはデフォルト値を定義することで実現されています。上記の WSDL フラグメントが何を表現しようとしているのかを見てみましょう。
-
Binding 要素
—
使わなければならないデフォルトの HTTP メソッドを
whttp:methodDefault を使って定義でき、クエリー・パラメーターのためのセパレーターを whttp:queryParameterSeparatorDefault を使って定義することができます。
-
Operation 要素
—すべてのオペレーションに対して、以下のパラメーターを定義するオプションがあります。
-
location
— このオペレーションの場所。たいていの場合は、相対 URI であり、完全な URI を形成するにはエンドポイント・ベースの URI (WSDL 2.0 文書の Endpoint 要素の中で定義されます) と組み合わせる必要があります。その URI のテンプレートをここで定義することができます。また、リクエストを送信する場合にも、エンドポイント・ベースと組み合わされて完全な URI を形成します。
-
method
— このオペレーションを呼びだすために使われる HTTP メソッド。値は GET、POST、PUT、DELETE のいずれか 1 つでなければなりません。
-
inputSerialization
— サービスに対してリクエストを送信する際の、データのシリアライズ方法。適切なコンテンツ・タイプを提供することで定義されます。
-
outputSerialization
— レスポンスを送信する際のシリアライズ方法。適切なコンテンツ・タイプを提供することで定義されます。
-
faultSerialization
— 失敗が起きたときのためのシリアライズ機構。
-
queryParameterSeparator
— クエリー・パラメーターのためのセパレーター。
下記は、GET 操作と POST 操作で利用できる、入出力シリアライズのデフォルト値です。
表 2. デフォルトの入力シリアライズと出力シリアライズ
| HTTP メソッド | デフォルトの入力シリアライズ | デフォルトの出力シリアライズ |
|---|
| GET | application/x-www-form-urlencoded | application/xml |
|---|
| POST | application/xml | application/xml |
|---|
WSDL 2.0 によって REST は実現されるのか
WSDL 2.0 に HTTP バインディング仕様が定義されている理由は、これによってサービスが SOAP バインディングと HTTP バインディングの両方を持てるためです。サービスの実装は、XML 要素として表現されることが多いアプリケーション・データの処理を行い、そしてサービスは、そのデータが SOAP エンベロープの中に入って受信されたものなのか、HTTP GET、あるいは HTTP POST として受信されたものなのかを認識しません。WSDL 2.0 の HTTP バインディングによって、HTTP メソッドを使って呼び出すことができるリソースとしてサービスを公開することができます。しかし同時に、HTTP バインディングによって完全な REST スタイルのシステムを実装できるわけではないことも理解する必要があります。これについては多くの人が頻繁に議論しており、すべては REST によって実現されるものを皆さんがどの程度信ずるかに依存します。
このシリーズの第 2 回では、Apache Axis2/Java と Apache Axis2/C という 2 つのオープン・ソースの Web サービス・エンジンで、どのように上記の概念が利用できるのかを探ります。
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | 
|  | Eran Chinthaka は、Apache Axis2 や Axiom、Synapse などのプロジェクトの当初からのメンバーであり、WSDL 2.0 と WS-Addressing のワーキング・グループのメンバーでもあります。 |
記事の評価
|