レベル: 初級 米持 幸寿, テクノロジー・エバンジェリスト, IBM
2005年 10月 14日 インターフェースがどういうものか、前回解説しましたので、今回はより技術的にインターフェースとはどのように定義していくものかを詳細に解説します。
前回説明したとおり、SOAに対応したIBMソフトウェアでは、インターフェースをWSDLで定義します。そのため、WSDLでインターフェースを定義するにはどのようにするべきか、を踏まえて解説していきます。
インターフェースの構造
データ型
インターフェースの最も小さな単位となる「素粒子」ともいえるのがデータの型です。データの型は大きくわけて基本型(Primitive)、複合型(Complex)、配列(Array)に分けられます。
旧来の分散プログラム技術において、基本型はint、long、double、float、boolean、byte、charといった近代的なプログラミング言語の基本型を使うのが一般的でした。また、メインフレームCOBOLなどでは、十進数のフィールドや、MIXED(半角と全角が混在してる)フィールドといった型もありました。
しかし、こういったものは、SOAシステムのインターフェースには向きません。なぜなら、これらのデータ型は、プログラミング言語や実行プラットフォーム独自のものであり、他の言語やプラットフォームと互換性がないからです。プログラミング言語非依存、プラットフォーム非依存の目標を満たすことができません。
SOAでは世界共通の標準に則ってインターフェースを定義するべきです。WSDLでは、WS-I.orgの規定に則って、XMLスキーマ・データ型(XML Schema Datatype=XSD)でデータ型を定義することが基本となります。これに従うことで、多くのプラットフォームがこのデータ型に対応することが可能だからです。
この方法は、XMLを基準にデータを考える方法です。しかし、アプリケーション・ソフトウェアを作る人にとっては、プログラム・インターフェース(Javaのinterfaceなど)から考えたい場合もあるでしょう。Javaの場合は、Javaの標準化団体Java Community ProcessのJSR-101「JAX-RPC仕様 1.1」の5.3章に掲載されている「Java to XML Type Mapping」を参考にします。
基本型、および、Java基本クラスのXMLデータ型との対応表を引用します。
<Java. API for XML-based RPC JAX-RPC 1.1より抜粋して引用>
見ていただいてお分かりのように、JavaではなじみのあるEnumeration、Vector、Hashtableなどは規定されていません。Java特有のコレクションクラスであり、他の言語と互換性がないからです。そういった型は、抽象インターフェースに持たせてはいけません。
WSDL 1.1 では、データ型は<types>要素で定義されます。基本は、XSDの方法による型定義です。
XSDでは、基本型を組み合わせた「complex」、同一の型のデータが並ぶ「array」なども定義されており、組み合わせて使うことができます。
メッセージ
データ型は組み合わせられて、操作のインプット、またはアウトプットとなります。これを束ねるのが「メッセージ」です。
メッセージを定義するコツは、インプットは操作名+Request、アウトプットは操作名+Responseとすることです。単純な基本型の入出力でもこのように定義して名前をつけます。(慣習的に、と覚えてください)
操作の失敗のときのためにFault型を定義することもできます。これも同様に操作名+Faultで定義するといいでしょう。
WSDL 1.1 では、<messege>要素で定義されます。
オペレーションとインターフェース
サービスの呼び出し単位、プログラムで言えばメソッドにあたるものを、サービス世界では「オペレーション(Operation=操作)」と呼びます。メッセージのインプット(Request)、アウトプット(Response)の組み合わせで操作を定義します。
機能的に意味のある単位(呼び出し順など)でひとくくりにできる単位でくくります。これがインターフェースの単位です。
WSDL 1.1では、<portType>要素と、その下の<operation>要素で定義されます。
結合技術の制限
データの型をXSDにしたがって定義し、メッセージ、オペレーション、ポートタイプと定義することで、インターフェースが定義できます。しかし、これだけのルールでインターフェースを定義してもSOAのサービスとして使いにくいものとなってしまいます。それは、サービスを結合するときの結合技術の制限によるものがほとんどです。 ここでは、あらかじめ気をつけなければならないことを簡単にリストアップし、より具体的には連載の回が進むにつれ詳細に説明していくことにしましょう。
ステートレスであること
ステートとは、あるメソッド(オペレーション)の組み合わせを数回行ったとき、以前の呼び出しのときの状態をサービス提供側(プロバイダー)が記憶しておいてくれるような機能を言います。
たとえば、買い物カゴに「メモリーを追加」という呼び出しのあと、「ハードディスクを追加」と呼び出したとき、買い物カゴにきちんとメモリーとハードディスクが格納されるということです。
ステートを管理することを「ステートフル」、管理しないことを「ステートレス」と言います。
CORBAやEJBでは、ステートを管理することができますが、JMSやSOAPではステートを管理するためのフレームワークは定義されていません。(WSRF=WebServices Resource FrameworkやGridサービスではステートを管理しますが、SOAでは標準ではありません)このため、サービスの操作は、ステートを持って複数回呼び出すことを前提にしてはいけません。
もし、複数回の呼び出しを想定する場合、アプリケーション機能としてステートを維持する機構を持つ必要があります。買い物カゴにたとえるなら、「どの買い物カゴを使っているか」を示すデータを、メッセージに含める、といった具合です。
コンテキストの共有を前提にしない
同様にCORBAやEJBでは、セキュリティーやトランザクションのコンテキストを共有することを前提に機能を定義することができますが、やはりSOAの世界ではコンテキストを共有することを前提にするべきではありません。
セキュリティーコンテキスト(シングルサインオンなど)や、トランザクションコンテキストを共有しなければならない場合は、これもアプリケーション機能かSOAシステムの基盤機能として独自に準備する必要があります。
例外は通知できない
サービスにはFault要素が定義できますが、これは単なる「失敗の通知」と考えてください。オブジェクト指向プログラミング言語が持つような例外通知の機構をサービス呼び出しが提供できるわけではありません。
名前の付け方
データ型、メッセージ型、オペレーション、ポートタイプなどには、すべて名前がつけられます。これらの名前は、ツールでプログラムコードを自動生成するときに使われます。名前は自由に付けられそうでそうでもありません。ツールの仕様によって使えない、あるいは、使うと不具合の起こる名前があります。
結合情報に関しては?
WSDLをよくご存知の方は、「binding要素とservice要素はどうなった?」とお考えの方もおられるでしょう。これらはプロトコルのための記述ですので、ここでは説明せず、あとで具体的な結合が行われるときに解説したいと思います。
表1. WSDL の構造
| インターフェース情報 | <types> | データ型情報 | | <message> | メッセージ定義 | | <portType> | サービス定義 | | プロトコル情報 | <binding> | 結合技術情報 | | <service> | エンドポイント情報 |
SOAでは、ここまでの「データ型」「メッセージ」「オペレーション」「ポートタイプ」で定義された「インターフェース」の単位でものを考えていきます。これがSOAのサービスのインターフェース定義です。プログラミング言語、プラットフォーム、ミドルウェアなどに依存しないインターフェース定義のため、「抽象インターフェース」と呼ぶこともあります。
次回から、実例を挙げて、ツールを使って具体的に「抽象インターフェース」を定義していってみます。
著者について  | |  | 1987年に日本アイ・ビー・エム入社。メインフレームOS、ミドルウェアの障害対応、障害解析ソフトウェアの開発、ワークフローシステム開発、オブジェクト指向開発、Web開発など経験。2000年より、ソフトウェアのテクノロジーエバンジェリストとして活動中。 |
記事の評価
|