ホーム > 読んだ > 国内

Webサービスの本質に迫る
ウェブサービスノホンシツニセマル

書誌

text唯野
author吉田豊
publisher技術評論社
year『Software Design 2002.2』p.105-120

履歴

2002.3.2x読了
2002.3.2x公開
2002.6.15修正

感想

Web サービスを主にその構成要素と実装例から捉えた記事。Web サービスのような使われ方というのは CORBA でもよくいわれていたことなので、Web サービスにおける UDDI というのは、CORBA でいえばインタフェースリポジトリ(IR)に近いものだといえる。そして、それをもう一歩進めると CORBA でいうトレーダ・サービスのようなものになる。これは、分散システムにおいて始めからサービスの利用する相手を固定せず(=実行時に)、その提供者をインタフェースではなく *求める機能から* 検索する。こういうのを読むと、Web サービスというのは CORBA での IIOP というプロトコルを SOAP (XML) による HTTP メッセージでラップしたもの――という印象を受ける。CORBA ではホスト間での通信を行うために TCP/IP ベースの IIOP というプロトコルを規定したが、それを更に上位レイヤとなる HTTP でカプセル化したということである。

だから、(そういうサービスに対応した CORBA の ORB 実装があれば)それはそのまま Web サービスとしても転用できることになるが、XML ベースの方が何より敷居が低く、既存の HTTP 技術をそのまま適用できるというのは大きい。WebDAV による共有ファイルアクセスでもそうだが、Web がこれだけ広がると HTTP と Web ブラウザこそが環境の差異を吸収した誰にでも分かる実際のアプリケーション・レイヤということになり、そういう意味での HTTP の利用というアプローチは今後も増えるのではないかと思う。少し前だとこういう場合、Socket を意識させないというのがポイントだったようなイメージがあるが、TCP/IP、もっといえば HTTP まで意識させないというのが Web サービスというもののひとつの特徴ではなかろうか。

とはいえ Web サービスはまだまだ仕様的に未成熟な部分がある。もちろん、その成熟スピードは相当の勢いで進んでいるので、次世代 Web のトレンドのひとつになるのは間違いないが、問題は技術として Java + JAX API と .net Framework のどちらに注目すべきかである。現時点で最も有力なソリューションが Java 陣営なのは自明だが、MS の .net もベンダ依存とはなるものの中間言語による言語独立性は既存のエンジニアには魅力的に映る。結果、Java をめぐる動きは Web サービスというレベルでの対立としても現れていることになり、個人としては双方に注目せざるを得ない状態が続きそうである。

追記

C マガでも Web サービスの特集があったので、その内容も含めてマージするようにしました。但し、.net によるサンプルまでは扱っていません。(持ってないんだから当たり前ですが...) (2002.4.23)

抄録

Web サービスは Web としてアクセス可能なサービスそのものやそれによる連携を指す。Web をベースとすることでプラットフォームや言語独立となり、やりとりされるデータも XML メッセージとして処理される。そして、各サービスはそれぞれにインタフェースを持ち、クライアントによる検索を行うことができる。そのため Web サービスでは XML をベースとしながら SOAP (Simple Object Access Protocol : Web サービスのメッセージ)、WSDL (Web Service Description Language : Web サービスの記述)、UDDI (Universal Description, Discover and Integration : Web サービスのリポジトリ)などを利用する。つまり、サービス提供者は WSDL で記述したものを UDDI に登録し、サービス利用者も同じく WSDL で記述した問い合わせを UDDI に行って必要な機能を検索、そして後は当事者間でメッセージをやりとりするかたちになる。

WSDL による UDDI への登録

サービス利用者による UDDI への検索

サービス利用者側での Web サービスへのバインド

SOAP による Web サービスの呼び出し

Web サービスではサービスは Web サーバより提供されるが、それを介した後の、その実際のアプリケーションはどこで動いてもよいし、既存のものをラップしてもよい。しかし、現状では Java が XML サポートや関連ツールでの対応面で優れている。例えば、JAX API (Java API for XML)を用いることで、Web サービスに対する親和性を高めることができる。これは具体的に以下のものなどがある。

  • The Java API for XML Processing (JAXP)
  • 標準的な XML インタフェース(DOM、SAX、XSLT)の提供
  • The Java API for XML Data Binding (JAXB)
  • XML データを Java コードにバインディングする
    XML スキーマの Java オブジェクトへのコンパイルというかたちを取る
  • The Java API for XML Messaging (JAXM)
  • SOAP メッセージ用のネイティブ Java インタフェース
  • The Java API for XML-based RPC (JAX/RPC)
  • SOAP RPC 用のネイティブ Java インタフェース
  • The Java API for WSDL (JWSDL)
  • WSDL ドキュメントの管理インタフェース
  • The Java API for XML Registries (JAXR)
  • XML レジストリ/リポジトリ用のネイティブ Java インタフェース

SOAP による XML ドキュメント

JAX API による相互のマッピング (JSP/Servlet)

アプリケーション (EJB/Servlet)

SOAP

SOAP は XML メッセージプロトコルで、基本的にピア・ツー・ピアでの一方向への通信を行う。現在は W3C で 1.2 の仕様策定が進められている。SOAP は基本的に以下の要素より構成される。

  • エンベロープ (Envelop)
  • 文字通り封筒であり、メッセージ内容の格納と処理内容の指示を行う。Header にそれらのメタ情報が記述され、Body にメッセージ本体が格納される
  • 符号化 (Encoding)
  • データがどのようなシリアライゼーションを行っているか。つまり、データをどう XML 化し、また復元するか
  • RPC (Remote Procedure Call)
  • 基本的に SOAP では Sender はフォーマットと送信先だけを扱い Receiver で処理内容の解釈を行うシンプルな形式を提供するが、RPC による複雑な通信もサポートする。その場合のパラメータや値の表現方法
  • バインディング (Binding)
  • SOAP エンベロープからトランスポート層のプロトコルへのマッピング。具体的な転送プロトコルとして HTTP を使う場合であれば、リクエストには POST メソッド、レスポンスにはエラーならばステータスコード 500 (Internal Server Error)と Fault 要素ほかを返すなど

SOAP メッセージの構造は HTTP ヘッダに続く HTTP 本体の中の SOAP エンベロープ(Envelope)内に SOAP ヘッダ(Header)と SOAP 本体(Body)の含まれるかたちになる。SOAP 本体は自由な XML 文書である。

このとき仲介者(intermediary) を含む SOAP 送信者(sender)から SOAP 受信者(receiver)までの SOAP ノードのセットのことを SOAP メッセージパスと呼び、特にスタート地点となる送信者のことを最初の SOAP 送信者(initial SOAP sender)、最後の SOAP 受信者のことを最後の SOAP 受信者(ultimate SOAP receiver)と呼ぶ。SOAP エンベロープでは、名前識別空間として http://schemas.xmlsoap.org/soap/envelope/ を使い、これを encordingStyle 属性で指定する。また SOAP ヘッダでは actor 属性でヘッダの処理をする URI、mustUnderstand 属性(0/1)でそれを無視できないかどうかを指定できる。また、メッセージ処理中に発生したエラー情報は Fault 要素によって送信者に返される。

なお、SOAP のサンプルに関しては 「SOAP 入門」 を参照されたし。

WSDL

具体的なサービスの内容、サービスが扱うメッセージ書式とプロトコル、アクセスポイントなどを記述する。WSDL は IBM と Microsoft によって開発され、現在 1.1 が W3C に提出されているが標準化はまだ行われていない。WSDL は以下の destinations 要素より構成される。

  • タイプ (types)
  • メッセージで用いられるデータ型に関するスキーマ
  • メッセージ (message)
  • メッセージ書式。複数持つことができる
  • ポートタイプ (portType)
  • operation の集まり
    • オペレーション (operation)
    • 操作。入力メッセージと出力メッセージより定義。複数持つことができる
  • バインディング (binding)
  • portType によるオペレーションとメッセージを具体的なプロトコルとデータフォーマットにマッピングする
  • サービス (service)
  • port の集まり
    • ポート (port)
    • あるエンドポイントのアドレス、つまり URL

アプリケーションは WSDL を元に実際に Web サービスの呼び出しを行うプロキシ(代理)を生成し、このプロキシが利用される Web サービスにバインドされる。WSDL ファイルは通常、自動生成されるが、手動生成/静的生成/動的生成のいずれでもよい。この辺りのリモートメソッド呼び出しがプロキシによって行われるというのは、デザインパターンにおけるプロキシパターンの代表的な使われ方であり、CORBA などでも同様である。

以下は http://www.w3.org/TR/wsdl にある WSDL のサンプルからの引用である。

<?xml version="1.0"?>
<definitions name="StockQuote"

targetNamespace="http://example.com/stockquote.wsdl"
          xmlns:tns="http://example.com/stockquote.wsdl"
          xmlns:xsd1="http://example.com/stockquote.xsd"
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
          xmlns="http://schemas.xmlsoap.org/wsdl/">

    <types>
       <schema targetNamespace="http://example.com/stockquote.xsd"
              xmlns="http://www.w3.org/2000/10/XMLSchema">
           <element name="TradePriceRequest">
              <complexType>
                  <all>
                      <element name="tickerSymbol" type="string"/>
                  </all>
              </complexType>
           </element>
           <element name="TradePrice">
              <complexType>
                  <all>
                      <element name="price" type="float"/>
                  </all>
              </complexType>
           </element>
       </schema>
    </types>

    <message name="GetLastTradePriceInput">
        <part name="body" element="xsd1:TradePriceRequest"/>
    </message>

    <message name="GetLastTradePriceOutput">
        <part name="body" element="xsd1:TradePrice"/>
    </message>

    <portType name="StockQuotePortType">
        <operation name="GetLastTradePrice">
           <input message="tns:GetLastTradePriceInput"/>
           <output message="tns:GetLastTradePriceOutput"/>
        </operation>
    </portType>

    <binding name="StockQuoteSoapBinding"
        type="tns:StockQuotePortType">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="GetLastTradePrice">
           <soap:operation
               soapAction="http://example.com/GetLastTradePrice"/>
           <input>
               <soap:body use="literal"/>
           </input>
           <output>
               <soap:body use="literal"/>
           </output>
        </operation>
    </binding>

    <service name="StockQuoteService">
        <documentation>My first service</documentation>
        <port name="StockQuotePort"
            binding="tns:StockQuoteBinding">
           <soap:address
               location="http://example.com/stockquote"/>
        </port>
    </service>

</definitions>

UDDI

UDDI は UDDI Project によって開発され、現在は 3.0 を策定中で、その後、標準化団体に提出される予定。UDDI は Web サービスにおけるディレクトリサービスということであり、UDDI のビジネス・レジストリは以下のようなかたちを取る。UDDI は汎用性を考慮されており、パブリックな UDDI が http://www.uddi.org/ で、その他プライベートな UDDI が IBM などから既に提供されている。

  • Business Entity (ビジネスの実体、情報)
    • ユニークなビジネス ID
    • ビジネス(企業)名
    • ビジネス内容の概要
    • 連絡先
    • URL
    • Business Service (サービス、業務の情報)
      • ユニークなサービス ID
      • サービス名と説明
      • サービスの分類 (業種など)
      • Binding Template (バインディング情報)
      • アクセスポイント(URL、メールアドレス、電話番号 etc)
        及び tModel のリスト
        • Service Types (サービスタイプ)
        • あくまでメタデータでありサービスそのものではない
          • tModel 名
          • tModel の発行元(企業名など)
          • サービスタイプの分類
          • 実際のサービスタイプ仕様へのポインタ

以下は http://www.uddi.org/ で提供されている UDDI 仕様に含まれる tModel のサンプルの引用である。

<tModel authorizedName="..." operator="..." tModelKey="...">
    <name>StockQuote Service</name>
    <description xml:lang="en">
        WSDL description of a standard stock
            quote service interface
    </description>
    <overviewDoc>
        <description xml:lang="en">WSDL source document.
        </description>
        <overviewURL>
            http://stockquote-definitions/stq.wsdl
        </overviewURL>
    </overviewDoc>
    <categoryBag>
        <keyedReference
            tModelKey="uuid:C1ACF26D-9672-4404-9D70-39B756E62AB4"
            keyName="uddi-org:types"
            keyValue="wsdlSpec"/>
    </categoryBag>
</tModel>

ebXML

(既に解散している)は <lnk http://www.oasis-open.org|OASIS> と <lnk http://www.unece.org/cefact/>UN/CEFACT がイニシアチブを取って開発しているもので、XML ベースによる電子商取引の情報/通信方式の策定を行っている。現在は各ワークグループの継続作業が上記の団体により行われている。ここではレジストリ : あるものに対する登録機能とメタデータの管理場所、リポジトリ : 実際のものの保存場所(データベース)という区別を行っており、ebXML は UDDI と比較してリポジトリまで持っている点で異なる。具体的にはレジストリ情報モデル(Registry Information Model : RIM)とレジストリサービス仕様(Registry Services Specification : RS)とからなり、これらはいずれも UML で記述される。仕様では実装まで規定していないので、レジストリとリポジトリの詳細は実装依存となっている。

レジストリ情報モデル (RIM)

RIM はレジストリで管理される登録データのメタデータを定義する。レジストリの扱うオブジェクトとして以下のようなものがある。実際に登録されたものが RepositoryItem (リポジトリ項目)となる。

  • RegistryObject (レジストリオブジェクト)
  • 全オブジェクトの継承元となり、全オブジェクトに共通の属性を持つ
  • RegistryEntry (レジストリエントリ)
  • AudiableEvent と User 以外の全オブジェクトの継承元となり、全メタデータに共通の属性を持つ
  • Association (関連付け)
  • RegistryObject 同士の関連付けを行う。属性である associationType に関連付けのタイプ(Extends, Supersedes, Replaces など)を指定する
  • ClassificationNode (分類ノード)
  • 分類スキーマを木と捉えた場合の個々のノード
  • Classification (分類)
  • RegistryEntry と ClassificationNode を結びつけることによって分類を行う
  • ExternalLink (外部リンク)
  • URI によって実際に登録されるものを示すオブジェクト
    • Package (パッケージ)
    • 複数の RegistryEntry をパッケージとしてまとめて登録する。Package と RegistryEntry は Association によって関連付けされる
    • User (ユーザ)
    • レジストリに要求を行ったユーザ情報の管理オブジェクト。AudiableEvent で管理される
    • Organization (組織)
    • RegistryEntry を登録した組織情報を管理するオブジェクト
レジストリサービス仕様 (RS)

RS は RIM で定義されたデータにアクセスするためのインタフェースを記述する。実際のインタフェースは XML メッセージとしてやりとりが行われるので、仕様ではそのための DTD を定義している。内容的には主に登録、削除、変更を行う ObjectManager と検索を行う ObjectQueryManager とに分かれる。

実装例

ebXML の実装例として Sun が試験的に提供している と <lnk http://www.sun.com/software/xml/developers/regrep/>ebXML Registry and Repository がある。ebXML Registry and Repository のアーキテクチャは J2EE コンポーネント(EJB コンテナ)としてマッピングされており、EJB Entity Bean によるレジストリ情報モデルは RMI によって Session Bean であるレジストリサービスとの通信を行っている。他にデータベース実装に依存しないベースアクセス API や XML ドキュメントとの Java バインディングを相互に行う API (DOM によるリクエストからのデータ抽出が不要になる)などが提供される。そして RegistryServlet (Web コンテナ)が JSP による検索ページと EJB コンテナを仲介し、JSP 用のタグライブラリによって Web ページの柔軟性が実現される。

参考文献

岡島幸男「体感 ! Webサービス Webサービスの基礎と.NET時代への対応」
C MAGAZINE 2002.5/p.44-55

Up