開発者:SOA

サービス・エンドポイントの標準化
Thomas Erl著

標準化されたサービス指向アーキテクチャのメリットが得られるサービス・インタフェース定義の設計方法を学習します。

2006年2月公開

注:この記事の一部では、Web Services Description Language(WSDL)の基本的な知識があることを前提としています。 WSDLに精通していない場合は、 オンラインWSDLチュートリアルを参照してください。

サービス指向アーキテクチャ(SOA)は、以前の分散コンピューティング・アーキテクチャよりも標準化への一貫した取組みを要求します。 広範なSOA移行の取組みによって、企業内の異なる技術的なプラットフォームの均一性とフェデレーションの実現をサポートする広範囲の標準化を組み込む機会が提供されます。

サービス指向ソリューションの一部として作成されたWebサービスは、公開するビジネス機能の潜在的なエンドポイントです。 一部のサービスに関するアクセスの制限または制御が必要な場合がありますが、ほかの多くのサービスを配置して、さまざまなソースからコンシューマーにアクセスできます。 標準化された方法でこれを実行すると、真のサービス指向エンタープライズへ成長するためのサポートがおこなわれます。

この記事では、サービス・インタフェース定義の設計中におこなわれた追加の作業によって、どのように標準化されたSOAをサポートできるかを説明します。 WSDLを使用するために一連の設計規則を確認し、標準化されたサービス・エンドポイントの作成をサポートするオラクルのSOAプラットフォームの最新の拡張機能も簡潔に説明します。

サービス指向の範囲

サービス指向アーキテクチャ・モデルで現在構築されているテクノロジー・プラットフォームは、分散コンピューティングの発展の次の段階を表します。 基礎となるSOAを定義するサービス指向設計パラダイムは、個別の自動化ロジック(サービス)の設計に大きく影響し、これらのサービスを使用する大規模な自動化環境の構造を構築します。

再利用、相互運用性、フェデレーションなどのサービス指向によって促進される原則は、個別のエンタープライズ・サービス、ソリューション、および統合環境の設計方法に大きく影響します。 この設計では、これらの環境で表される個別のエンタープライズ・ドメインがどのように存在し、動作し、相互に関連するかを決定します。 SOAモデルで外部の異なる環境を標準化されたサービス・インタフェース・レイヤーで使用できますが、最初から標準を実装および実施した場合のみ、このおもな利点を活用できます。

標準の影響

ほかのフレームワーク、テクノロジー・プラットフォーム、またはアーキテクチャ・モデルと同様に、主要な原則が乱用される場合があります。 使用可能なアプリケーション・スコープが幅広いため、サービス指向コンピューティング分野の乱用という大きな危険性があります。 内部標準を使用して遵守する文化が組織にない場合、この概念を導入することは大きな課題となります。

標準開発段階で、組織の優れた専門家が現在の環境の制約を評価し、通常の移行作業による技術的および組織的な変更とともに戦略的なSOA構想の目標に対する調整をおこなう必要があります。 標準を作成すると、多くの時間と労力が費やされて多くの意思決定が含まれる可能性があることがわかります。

標準が確定してから、その使用方法をプロジェクト・ライフ・サイクルに組み込む必要があります。 標準の使用を推奨する場合、実際に標準を作成するよりも困難になる場合があります。 多くの場合、創造性および開発プロセスの柔軟性を低下させるルールと見なされるため、標準には多くの障害があります。

反抗的な開発者は、プロジェクト・チーム・メンバーがさまざまな設計オプションを繰り返し調査することを避ける境界を確立して、標準を使用してソリューション・プロセスを実際に効率化できることを発見するでしょう。 これによって、開発前プロジェクト段階の多くの時間が節約され、全体のソリューション設計を簡素化できます。

ただし、エンタープライズ全体のSOA移行構想をサポートする標準は、個別のプロジェクトに負荷を与えます。 たとえば、再利用を強調するには、現在のソリューション・スコープの外部で役立つ自動化ロジックを識別する追加の時間と労力が必要になる場合があります。

反対に、再利用可能なサービスがすでに存在する場合、プロジェクトで機能を追加できないことがあります。 この場合、開発者には、1つ以上の既存のサービスのソリューションの組込みおよび構築が要求されます。

このような多くの状況によって、全体のソリューション設計に複雑さが追加され、予算と今後の予定に悪影響がある場合、SOAをサポートする標準が個別の開発プロジェクトに余分な負荷を与えることがわかります。

予測可能なサービス指向エンタープライズの確立

さまざまなレベルのサービス指向環境で、標準を適用できます。 最上位レベルで、サービス・レジストリなどのインフラストラクチャ・コンポーネントとともに、アーキテクチャの仕様およびほかのタイプの内部ドキュメントを標準化できます。

正常なサービス指向の実現に不可欠である見落とされがちな設計標準は、個別のサービスに適用される標準です。

Webサービスとしてサービスが実装されると、その重要性が高まります。 Webサービスを基礎にする独自仕様ではない通信フレームワークによって、企業の一部によって利用されるサービスがサービス・リクエスタとして参加できる機会が広がります。 企業内の標準化されたWebサービスのインベントリが増加するにつれて、すでに開発および配置されたサービスの投資を再活用する強力な手段になります。

現在、Webサービスは、SOAを標準化する主要な手段を提供します。ただし、これを実行するには、WSDL定義の所有権を仮定する必要があります。 以下の記事で、サービス指向をサポートする標準を使用してサービス・インタフェースを構築する方法を確認します。

WSDLの制御

Webサービスを構築する"WSDL First"アプローチでは、開発者がほとんどの開発ツールで提供される自動生成ユーティリティを使用するのではなく、WSDL定義をカスタマイズして手動でサービス・インタフェースを定義する必要があることが示されています。 このアプローチの利点は、開発者がサービスのインタフェースおよびカプセル化されたロジックで使用する制御レベルです。

インタフェース・レベルの標準化を理解するには、Webサービス・インタフェースを構成するWSDL定義を分割する必要があります。 WSDL定義は、W3C WSDL仕様で定義されているXMLドキュメントで、サポートするサービス・インタフェースと実装を正式に表す抽象的および具体的な説明を含みます。 メッセージ・データの特性に影響を与えないで実装の詳細を変更できるように、これらが分割されます。

具体的な定義は既存のテクニカル・インフラストラクチャによって影響または定義される場合が多いので、この記事では、次の設計の考慮事項が適用される抽象的な定義の設計を中心に説明します。

  • サービス・インタフェースの粒度 - サービスによってカプセル化されたロジックが分割され、サービス操作を通じて使用できます。
  • サービス・データ交換要件 - 特定のメッセージング要件が確立されます。
  • サービス・データ表現 - データ構造とデータ型が定義または参照されます。
  • サービス・インタフェースのラベルづけ - ネーミング規則がサービス・インタフェース自体に適用されます。


図1:標準を適用できる抽象的なWSDL定義の領域


これらは、全体のサービスの品質とユーザビリティに役立つ抽象的な定義設計の主要な側面です。 1つずつ確認します。

サービス・インタフェースの粒度

サービスの基礎となるロジックをパブリック・インタフェースで表現する方法の決定は、サービス設計のもっとも困難な部分になります。 これによって、操作をおおまかにするか詳細にするか、組織内で多くの議論がおこなわれる可能性があります。

通常、詳細な操作は、特定のタスクを完了するための少量のパラメータ・データの交換を中心とするリモート・プロシージャ・コール(RPC)タイプの通信パターンと関連づけられます。 同じサービスでほかのタスクを実行する必要がある場合、ほかのサービス操作は、あとで呼び出されます。 例1は、詳細な操作の定義に使用される"message"および"operation"の構文を示しています。

詳細なアプローチの既知の短所は、サービス操作のメッセージ・ベースの呼出しが高価なため、大きいプロセスの小さいサブタスクを実行する場合に個別のメッセージの送信および処理のオーバーヘッドが非効率になることです。

おおまかな操作は、単一のサービスの呼出しで幅広い機能を公開します。 多くの場合、これによって、さまざまな小さいタスクが単一のおおまかな操作に変換されるので、 例2のように単一のリクエスト・メッセージの送信で多くの処理を実行できます。

おおまかなアプローチの長所は、リクエスタとプロバイダのラウンドトリップや対応する処理サイクルが少なくなることです。 短所は、おおまかな操作によって実際に必要な機能よりも多くの機能が頻繁に公開されることです。 そのため、一部のリクエスタがサービスに実行させる処理にデータの一部だけが関連する場合、すべてのサービス・リクエスタから多くの入力値または大きいドキュメント構造を要求することがあります。

サービス設計全体のサービス指向を促進する単一のレベルの粒度を標準化することは困難です。注意すべき主要な目標は、プロセスで直接のソリューションやビジネス・ドメインの調査および投機分析に必要なソリューションを提供するプロジェクトのバランスを取ることです。 このバランスによって、現在および将来のデータ交換要件を簡素化する粒度レベルがサービス・インタフェースで実現します。

サービス・データ交換要件

サービスが公開する操作とそれぞれにカプセル化されるロジックを決定したあと、操作での処理の実行に必要な入力値と出力値を把握する必要があります。 このような設計の決定の複雑さは、インタフェースの粒度のレベルに関連します。 詳細な操作では、簡単なデータ交換要件が一般的です。おおまかな操作では、さまざまな入出力データセットの組合せが導入されることがあります。

多くの不要なデータの転送を必要とするおおまかな操作の問題を回避する一般的な方法は、オプションのパラメータを使用することです。 操作にはさまざまな関連機能を実行できますが、実際に実行される機能は受け取られるパラメータによって決定されます。 したがって、操作で返される出力値は、実際に実行された処理によって異なる場合があります。

実用的で拡張可能ですが、オプション・パラメータの使用はWebサービス内に制限されます。 オプション・パラメータを使用すると、複雑なサービス・インタフェース設計および多数の入り組んだデータ交換シナリオになる場合があります。 また、多くの場合、オプション値の使用範囲は、メッセージ構造を定義する基礎となるXMLスキーマによって制限されます。 確立された企業ドキュメントを表す標準化されたスキーマは、厳密なデータ構造を要求することがあります。

関連する考慮事項として、サービス操作の通信に一方向または双方向のどちらのデータ交換が必要かどうかを検討します。 RPCの時代には同期パターンが多くの設計者および開発者に浸透していましたが、メッセージ・フレームワークでは、非同期交換パターンをサポートする一方向のデータ転送によって要件が効果的に満たされる場合が一般的です。 詳細に説明された標準およびガイドラインによって、サービス設計者および開発者は一貫した方法でこれらの問題を処理できます。

サービス・データ表現

本格的なWSDL定義の中心は、明確に定義されたXMLスキーマです。 全体のサービス・ロジックを表すWSDL定義と同様に、特定のビジネス・プロセスまたはソリューション環境の観点から、入出力サービス・メッセージのデータ構造を定義するXMLスキーマを再利用可能で独立仕様にすることが重要です。 一元化された一連のスキーマを構築して横断的な情報セット(異なるソリューション環境で使用されるデータ本体)を表現すると、多くの冗長なスキーマ設計が回避され、一貫して純粋なデータ表現アーキテクチャに役立ちます。

つまり、適切に標準化されたサービス・エンドポイントでは、基礎になるXMLスキーマ定義の標準化が必要です。 既存のデータ・モデルを使用して設計された場合と比較して、特定のWSDL定義用に構築された場合、XMLスキーマは通常異なって見えるので注意してください。 たとえば、Webサービス専用に作成されたスキーマでは、 例3のようにサービス・リクエストおよびレスポンス・メッセージを参照するネーミングを組み込むことが一般的です。 一方、企業ドキュメントを表すために設計されたXMLスキーマ内の要素は、このドキュメントだけに関連づけられます( 例4を参照)。

スキーマ・モデリング標準の使用によって、標準化されたサービス・インタフェースの開発に必要なステップに似ている追加の分析ステップが導入されます。 この分析の基本概念は、再利用機能が基礎となるサービス・ロジックに直接関連づけられていない限り、特定のWebサービス用に再利用可能なデータを表すスキーマを設計してはいけない点です。

サービス・インタフェースのラベルづけ

明確に定義されたサービスは、明確なコンテキスト内の個別の機能をカプセル化します。 目的と範囲が事前に十分に検討されているため、このようなサービスのラベルづけは一般的に簡単です。 残りの処理は、これを潜在的なサービス・リクエスタに簡潔に伝えることです。

明確に定義されていないサービスでは、多くの問題が発生する可能性があります。 サービスで表現される操作が論理コンテキストを通じて関連づけられていない場合、サービス機能を正確に表す名前を検出することが困難になります。

最初からサービスを設計する場合、一連の既存のサービス・モデルに従ってサービスを分類すると便利なことがわかります。 これらのモデルは、提案されたコンテキストとサービスをモデル化できる境界をすでに確立しています。 一般的なサービス・モデルには、アプリケーション・サービス、エンティティ中心のビジネス・サービス、およびタスク中心のビジネス・サービスが含まれます。 これらは、ユーティリティ中心、エンティティ中心、タスク中心のサービス・コンテキストをそれぞれ確立します。 (拙著の『Service-Oriented Architecture: Concepts, Technology, and Design』でサービス・モデルの詳細を取り上げています。)

  • ユーティリティ中心のコンテキストは、イベント・ロギング、例外処理、通知などの横断的な機能をカプセル化する操作を含むアプリケーション・サービスにあります。 ソリューション環境に依存しない特定の処理コンテキストに従って、これらの再利用可能なサービスのラベルづけをおこなう必要があります。 たとえば、ユーティリティ・サービスにNotifyという名前がつけられる場合があります。
  • エンティティ中心のコンテキストは、請求書や発注書などの特定のビジネス・エンティティを表すビジネス・サービスで確立されます。 多くの場合、エンティティ中心のビジネス・サービスのラベルづけは、エンティティ名によって事前に決定されます。 たとえば、サービスにInvoiceやCustomerという名前がつけられる場合があります。
  • プロセス・ロジックをカプセル化するためにモデル化されたサービスには、タスク中心のコンテキストが必要です。 この場合、グループ化された操作を統合するスレッドは、サービス・ロジックによって自動化される特定のアクティビティです。 このため、サービス名に動詞を使用することが一般的です。 たとえば、タスクのスコープを正確に表す場合、タスク中心のサービスがGetProfileやProfileRetrievalと呼ばれることがあります。

サービス名と同様に、個別のサービス操作のラベルづけは、標準およびガイドラインに準拠したすでにいくつかのベスト・プラクティスが存在するプロセスにもなります。

たとえば、サービス自体のネーミングは、個別の操作のラベルづけに影響します。 適切なサービス名が意味とコンテキストをすでに確立しているため、操作名を合理化して、冗長な用語の使用を回避する必要があります。 Invoiceというサービスの請求書の履歴データを取得する操作を仮定します。 請求書のコンテキストがサービス名ですでに確立されているので、この操作にGetInvoiceHistoryというラベルをつける必要はありません。 GetHistoryで十分です。

操作のラベルづけの別の考慮事項は、操作とサービス自体でカプセル化されたロジックの再利用性です。 再利用可能な場合、操作の機能を特定のアクティビティまたはタスクに関連づける名前を避ける必要があります。 つまり、多くの場合、一般的な操作名を選択して今後の再利用の機会を考慮することが賢明です。 たとえば、GetCurrentWidgetPriceという名前の操作をGetCurrentPriceやGetPriceにすることが適切な場合があります。

最初はネーミング規則を重視しませんが、サービス・インベントリが増加すると、個別のサービスの統合チャネルを再利用、再活用、および実現する可能性も高まります。 これは、大企業で、多くの設計者、アナリスト、および開発者がソリューション設計内の外部サービスを検出して組み込んでいることを意味します。 相互運用性と再利用の機会を簡単に認識および把握すれば、すべてのサービス・エンドポイントの一貫したレベルの明確さを確立するために必要な労力がすぐに報われます。

標準化されたサービス・エンドポイントおよびOracle SOAプラットフォーム

オラクルは、さまざまな技術委員会への貢献とOracle BPEL Process ManagerなどのWebサービス・テクノロジーの実装による過去数年間のWebサービス・テクノロジー環境の発展をサポートしてきました。

オラクルは、SOAベースのコンピューティング・プラットフォームへの業界規模の移行も公的にサポートしてきました。 Oracle JDeveloper 10g Release 3のWSDL First開発アプローチのサポートを発表した際に、サービス・エンドポイントを標準化する権限をソリューション開発者に付与する必要性をオラクルが認識していたことが最近明らかになりました。 追加の自動生成や開発者が精通しているウィザード・ドリブンな機能を提供する以外に、このバージョンはWSDLエディタも提供します。 これで、派生ではなくWebサービスを設計できます。したがって、標準化されたSOAを実現するために必要なコントロールが追加されます。

長期的な提案

SOAエンドポイントの標準化は、多くの先行投資、忍耐、および統制を必要とする継続的なプロセスです。 SOAの移行を正しく管理するには、SOA内の標準化を実現する初期コストによってどれだけ測定可能なエンタープライズ・レベルの向上につながるかを企業全体で把握することが重要です。

すべてサービスから開始されます。 標準がインタフェース・レベルに適用されると、データ共有および高度な複合ソリューションを促進する一貫したエンドポイントを使用した純粋なサービス指向環境の基盤が構築されます。


Thomas Erl氏は、SOA Systems Inc.の設立者で、世界中でベストセラーとなっているSOAの書籍『Service-Oriented Architecture: A Field Guide to Integrating XML and Web Services』(Prentice Hall PTR、2004年)および『Service-Oriented Architecture: Concepts, Technology, and Design』(Prentice Hall PTR、2005年)の著者です。

例1

GetProfileName操作は、プロファイル名の出力値を取得する検索基準として使用される単一の入力値を要求します。 この場合、入力値と出力値は、簡単なネイティブXSDタイプとして表されます。 (詳細なメッセージを定義するために簡単な要素の構文を使用した複雑なタイプも使用できます。)

<definitions ...>
...
<message name="GetProfileNameRequest">
        <part name="ProfileID" type="xsd:int"<//>
</message>
<message name="GetProfileNameResponse">
        <part name="ProfileName" type="xsd:string"<//>
</message>
...
<operation name="GetProfileName">
        <input message="tns:GetProfileNameRequest"<//>
        <output message="tns:GetProfileNameResponse"/>
</operation>
...
</definitions>

例2

GetProfileInfo操作は、複雑なタイプの構文を通じて検索基準の複数の入力値を受け入れます。 同様に、この操作は、複数の出力値(その1つがプロファイル名)を使用できる複雑なタイプに対応します。 このタイプの操作は、柔軟なスキーマで設計される場合におおまかな操作として分類されますが、詳細なデータ交換とおおまかなデータ交換の両方に対応できます。

<definitions ...>
...
<message name="GetProfileRequest">
        <part name="RequestValue" element="act:GetProfileRequestType"<//>
</message>
<message name="GetProfileResponse">
        <part name="ResponseValue" element="act:GetProfileResponseType"/>
</message>
...
<operation name="GetProfileInfo">
        <input message="tns:GetProfileRequest"/>
        <output message="tns:GetProfileResponse"/>
</operation>
...
</definitions>

例3

"part"要素で参照されるタイプは、この特定のWebサービス内のロールから名前がつけられます。

<message name="GetProfileRequest">
        <part name="RequestValue" element="act:GetProfileRequestType"<//>
</message>
<message name="GetProfileResponse">
        <part name="ResponseValue" element="act:GetProfileResponseType"/>
</message>

例4

これらの"part"要素で参照されるタイプは、さらに汎用的です。 親の"message"要素名と関連づけられている場合、目的が明確になります。

<message name="GetProfileRequest">
        <part name="RequestValue" element="act:Profile"<//>
</message>
<message name="GetProfileResponse">
        <part name="ResponseValue" element="act:ProfileReport"/>
</message>
 

ご意見ご感想をお寄せください。