本文へジャンプ

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

送信されたすべての情報は安全です。

  • 閉じる [x]

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


送信されたすべての情報は安全です。

  • 閉じる [x]

PerlでXML-RPCを始めよう 第2回:XML-RPC Middleware

Web ServicesへのXML-RPCの使用: 第2回

Joe Johnston (jjohn@cs.umb.edu), Senior Software Engineer, O'Reilly and Associates
Joe Johnston (jjohn@cs.umb.edu) は、昼間はO'Reilly and Associatesでプログラマーとして勤務しています。愛猫がキーボードの上にいないときには、Perl Journal、use.perl.org、www.perl.com、およびO'Reilly Networkのために記事を書いています。また、Michael Lordと協力して、ユーモラスなUFO伝説のサイトAliens, Aliens, Aliens も作成しました。

概要: 一般的なWebアプリケーションでは、ハードウェア・リソースが足りなくなることがしばしばあります。Web Servicesミドルウェアを使用すれば、デベロッパーはアプリケーション・アーキテクチャーをそのミドルウェアによって接続された複数の論理コンポーネントに分割することにより、パフォーマンス上のボトルネックを除去しやすくすることができます。これを行うには、問題の領域により優れた処理を追加するだけです。XML-RPCは、ミドルウェアを構築する際の労苦を必要としない、単純なWeb Servicesプロトコルです。

日付:  2001年 3月 01日
レベル:  初級 この記事の原文:  英語
アクティビティー: 1580 ビュー
お気軽にご意見・ご感想をお寄せください: 


ミドルウェア: アプリケーション・コンポーネントの疎結合

前の記事 (参考文献を参照) において、私はXML-RPC (参考文献を参照) を、リモート・マシン上で機能を実行する容易な方法として紹介しました。しかしながら、この機能だけでは、このプロトコルを学ぶ価値はそれほどありません。この記事ではこの機能の代わりに、XML-RPCと関連する興味深いWeb Servicesのアプリケーションであるミドルウェアについて調べます。

最も基本的なレベルにおいて、ミドルウェアはまさにアプリケーション・プログラミング・インターフェース (API) を使用してリソースへのアクセスを抽象化する手段ということができます。関数型プログラミングとオブジェクト指向プログラミングではどちらでも、APIを使用して、プログラマーの便宜のためにソフトウェア・リソースの操作に関する詳細 (ユーザー認証データベースやファイル・システムなど) を単純化します。明らかに、APIを呼び出すユーザーは、基礎を成すインプリメンテーションの詳細から守られるため、このような抽象化から益を受けます。ただし、APIのインプリメンテーション担当者は、古いインプリメンテーションを使用しているプログラムを破壊しなくても基礎を成すライブラリーを徹底的に変更することができるため、この抽象化から益を得られるかどうかは明らかではありません。

コードのインプリメントと呼び出しの間でこのような独立性を認めるソフトウェア・ライブラリーは、疎結合と見なされます。呼び出し側のコードで、APIやライブラリー・コード内にある操作されたデータ構造が無視されると、ライブラリーのインプリメンテーションの変更時に正しく動作しないクライアントが破壊される可能性があるため、この独立性は失われます。このようなシステムは、密結合と呼ばれます。優れたソフトウェア・エンジニアリングでは、システムが可能な限り疎結合になっている必要があります。

APIの考えは、プログラミング・ライブラリーを超えた大きな概念に拡張することができます。もちろん、ユーザーがデータベースの内容をグラフィカルに変更できるようなアプリケーションは、それ自体がロー・データを操作できなければなりません。MySQLやPostgreSQLなどのデータベースには、この目的のためにCインターフェースが備わっています。この仮説アプリケーションが特定のリレーショナル・データベース管理 (RDBM) システムのネイティブ・インターフェースを直接使用している場合、新しいRDBMシステムに切り替える際に以前のシステムと対話していたコードをすべて作り直す必要が生じます。表示論理と特定の基礎データベースを処理するために必要なルーチンとの間のすべてのコミュニケーションを調整するミドルウェア層を導入すれば (図1 を参照)、プログラマーはAPIというフェンスのいずれの側に対しても、他方の側に対応する変更を行わずに、徹底的な変更を加えることができます。


図1: 典型的なミドルウェアのセットアップ
図1: 典型的なミドルウェアのセットアップ

Webアカウントの集中管理: 現実の例

簡潔な理論的背景を得たところで、現実世界の問題をXML-RPCミドルウェアによって解いてみましょう。

ログインが必要なユーザー・アカウントが存在するWebサイトを考えてみましょう。Apacheに組み込まれたHTTP認証を使用すれば、ユーザー名とパスワードを保管することができます。多くの場合、該当ユーザーが認証された時点で使用可能になる、他のアカウント固有のデータも保管しなければなりません。これは、アカウント情報をMySQL (参考文献を参照) などのRDBMシステムに保管すべき理由となります。フロントエンドがPerlやPHPで作成されていれば、MySQLへのアクセスをCGIスクリプトにハードコーディングすることは魅力的でしょう。しかしながら、これを行うと、表示論理と特定のRDBMシステムが密結合になります。そこで、ミドルウェアが登場します。ミドルウェアは、基礎を成すRDBMをシームレス (継ぎ目なし) に変更できることに加え、単一のデータベース・サーバーを一群のマシンに置き換えることができる、柔軟なシステムを実現します。ミドルウェアの使用によって実現する疎結合は、スケーラブルなWebアプリケーション・アーキテクチャーを作成するかぎとなります。

フロントエンドのCGI表示コードとバックエンドのデータベースおよびビジネス論理コードとの間にミドルウェア・ブリッジを構築するには、必要なすべてのデータ・アクセスを許可するAPIを定義する必要があります。表1 は、このアプリケーションのユーザー・アカウント・データ・ストアに使用するXML-RPCミドルウェアAPIを示しています。フロントエンド・コードは、これらのXML-RPC呼び出しを行うことによってのみ、基礎となるデータを取得することができます。


表1: アカウント情報用のXML-RPC API

ホスト:

http://marian.daisypark.net/RPC2

ポート:

1080

プロシージャー定義

プロシージャー名

入力

出力

説明

authenticate

<string>, <string>

<int>

ユーザー名とパスワードを指定すると、証明書が一致した場合に新規セッションIDを戻します。

get_account_info

<int>

<struct>

有効なセッションIDを指定すると、そのIDに関連したユーザーのアカウント情報を戻します。この構造には以下のフィールドがあります。
username
fullname
points

set_account_info

<struct>

<int>

以下のフィールドを含む構造を指定すると、
username
fullname
password
points
usernameが新規であれば新規アカウントを作成し、そうでなければ既存アカウントを更新します。さらに、成功すれば1を戻し、失敗すれば0を戻します。


ユーザーがこの架空のサイトにログインしようとすると、ユーザー名とパスワードの入力を求めるHTMLフォームが表示されます (図2 を参照)。ユーザーが発信ボタンを押すと、フォームを処理するCGIスクリプトにより、Perlリスナーに対してauthenticate() XML-RPC呼び出しが出されます。ユーザーの証明書が有効であれば、フロントエンドはセッションIDを受け取り、それを使用してサイトでユーザーをトラックするか、他のアカウント情報を検索することができます。この例では、ユーザーがログインすると、アカウント情報を更新できるページに移動します。


図2: IDとPWの入力を求めるHTMLフォーム
図2: IDとPWの入力を求めるHTMLフォーム

PHPクライアント

フロントエンドのWebコードを開発する上で、PHPより優れた言語はほとんどありません。リスト1 は、図3 のログイン画面を生成するPHPコードを示しています。


図3: PHPによるログイン
図3: PHPによるログイン

PHPの初心者は、PHPのホーム・ページ (参考文献) を参照してください。他のサーバー・サイド組み込みテクノロジー (Active Server PagesやColdFusionなど) と同様、PHPでは静的ページと動的コンテンツの境界があいまいになっています。ログイン・ページのコード (リスト1 を参照) は、最初にXML-RPC PHPライブラリーをプルします。ユーザーがユーザー名とパスワードを入力すると、新規のxmlrpc_client オブジェクトがURLとTCPポート番号で初期化されます。PHPの場合、このオブジェクト初期化ルーチンの引数は、pathhost、およびport です。

Perlライブラリーと同様に、PHPを使用すれば、プログラマーは基礎を成すXML-RPC対話をデバッグのために参照することができます。6行目と7行目では、RPCの引数となるオブジェクトを作成します。各引数は、特殊なオブジェクトにラッピングして、PHPライブラリーが値をXMLに正しくエンコードできるようにする必要があります。

8行目では、RPC呼び出しの内容をエンコードする新規xmlrpcmsg オブジェクトを作成します。このオブジェクトには、リモート・プロシージャー名の後に、すべてが1つのPHP配列オブジェクトにラッピングされた引数のリストを指定する必要があります。最後の9行目では、XML-RPCリスナーとの接続が確立され、応答オブジェクトが戻されます。リスナーが戻した値を検索するには、応答オブジェクトに保管されたxmlrpcval オブジェクトを取得してから、xmlrpcval オブジェクトのスカラー値を要求します。なぜスカラー値なのでしょうか? APIのことを思い出してください。authenticate() がある種の整数を戻すことが宣言されていました。この正数が非ゼロであれば、これはセッションIDであり、ユーザーはセッションIDがURLに結合されたアカウント保守画面に移動します。authenticate() が失敗すると、失敗メッセージが発行され、ユーザーは再びログインする機会を与えられます。

リスト2 はXML-RPCではなく、SQLで構成されています。読者はすでに、PerlのDBIモジュールについていくらかご存じでしょう。そうでない場合は、MySQLのメイン・ページ (参考文献 を参照) をお読みください。ここには、このモジュールの使用についての完全な紹介があります。

4~7行目ですべてのライブラリーをプルした後、すべてのサブルーチンがデータベースへのアクセスに使用するグローバルDBIハンドル$Dbh が作成されます。END() サブルーチンはスクリプトの終了時に実行され、データベースから明示的に切断しないことに関連したDBIエラー・メッセージの発生を確実に抑えます。15~22行目では、発行されたAPIプロシージャー名がそのプロシージャーをインプリメントするPerl関数と関連付けられます。

36行目は、認証が行われる様子を示しています。この関数では2つのスカラーが必要です。これらは、必要なサイズと形状を満たしているかどうか確かめられます。SQLテーブルusers が照会され、証明書が一致するかどうかが検査されます。リスト3 は、このテーブルを作成したSQLコードを示しています。


リスト3: usersテーブルを作成したSQL
                
<![if !supportEmptyParas]> <![endif]>
      create table users (
      username char(12) not null default '',
      password char(13) not null default '',
      fullname char(50) not null default '',
      points     int default 0,
      Primary Key (username),
      index (fullname)
      

ユーザー名が一致する行を検索するSQLステートメントが用意されています。ユーザー名は基本キーなので、最低でも1つは一致する行があります。"password" という名前でDES暗号化ストリングである1つの列が戻されます。Perlのcrypt() 関数により、渡された$password がDES暗号化され、このスカラーがテーブル内で見付かったものと比較されます。これらのストリングが一致すると、このイベントはlogger() 関数を介して別のMySQLテーブルに記録され、新規のセッションIDが生成されます。210行目のnew_session_id() 関数は、ユーザー名をsessions テーブルに挿入するだけです。リスト4 は、sessionsテーブルを作成したSQLコードを示しています。



リスト4: sessionsテーブルを作成したSQL
                
create table sessions (
        id int auto_increment not null primary key,
        username char(13),
        issued timestamp
);


セッションIDは単なるauto_increment フィールドです。挿入が実行されるたびに、固有の新規IDと挿入発生時のタイム・スタンプが作成されます。MySQLのすばらしい点は、DBIハンドルのmysql_insertid 属性を使用すれば、最後に使用された挿入IDを容易に識別できることです。その後、この整数はXML-RPCクライアントに戻されます。

セッションIDが生成される秘密が明らかになったところで、そのセッションIDを使用する関数について考えましょう。66行目で、get_account_info() が始まっています。これには、有効なセッションIDを渡す必要があります。セッションIDはsessions テーブルに属していますが、必要な情報はusers テーブルに保管されていることを思い出してください。必要な情報を取得するには、SQLJOIN 演算子を使用します。sessionsusers のどちらにも、"username" という名前のフィールドがあります。sessions でセッションIDが入っている行を見付ければ、そのセッションのユーザー名も見付かります。このユーザー名を使用して、users でそのユーザー名が入っている行が検索されます。これが成功すれば、その行がハッシュ参照として取り出され、呼び出し元に戻すことができます。このSQLが少し分かりにくい場合は、2つの小さなSELECT 呼び出しを使用して、行を手作業でPerlハッシュと結合してください。

最後の関数はset_account_info() で、構造を必要とします。このXML-RPC構造は、Perlではハッシュ参照として表されます。この関数はINSERTUPDATE を行うので、これら2つのSQL操作の間に競合状態が起こらないように、users テーブルはロックされます。理想的なのは、トランザクションをサポートしている最新バージョンのMySQLを使用することですが、依然として以前のMySQLが多く出回っているため、トランザクションが歴史的にこのRDBMで処理されてきた方法を理解しておくのは役立ちます。

DBIのdo() メソッドは、実行されたSQLステートメント (種類は関係ない) に影響された行の数を戻します。この戻り値を使用すれば、アカウントの更新や作成が必要かどうかを知ることができます。既存のユーザーだけが自分のフルネームやいくつかの点を変更できることを思い出してください。"username" フィールドは基本キーであり、このフィールドの変更はより制御された方法で行う必要があります。明らかにパスワードはここで変更することができますが、この処理は別の関数に分離したほうがよいように思えます。更新が完了すると、テーブルはアンロックされ、このトランザクションはlogger() によってログに記録されます。新しいアカウントを作成しなければならなくなると、テーブルはアンロックされ、パスワードが暗号化された後でこの情報がINSERT されます。このときも、操作の成功または失敗がXML-RPCクライアントに戻されます。


実例の向こう側

SQL、XML-RPCリスナー、およびクライアントのコードの行数を数えると、このミドルウェア・システムは600行以内のコードで済んでいます。XML-RPCは強力で単純なメッセージ受け渡しシステムであり、この記事で説明したようなアプリケーションにおいて際立っています。XML-RPCの後継者はSimple Object Access Protocol (SOAP) (参考文献を参照) であり、この記事で説明した一部の機能が拡張されています。SOAPについては、次の連載記事で扱います。XML-RPCについて詳しくは、ホーム・ページ (参考文献を参照) をご覧ください。


参考文献

著者について

Joe Johnston (jjohn@cs.umb.edu) は、昼間はO'Reilly and Associatesでプログラマーとして勤務しています。愛猫がキーボードの上にいないときには、Perl Journal、use.perl.org、www.perl.com、およびO'Reilly Networkのために記事を書いています。また、Michael Lordと協力して、ユーモラスなUFO伝説のサイトAliens, Aliens, Aliens も作成しました。

不正使用の報告のヘルプ

不正使用の報告

ありがとうございます。 このエントリーは、モデレーターの注目フラグが設定されました。


不正使用の報告のヘルプ

不正使用の報告

不正使用の報告の送信に失敗しました。


developerWorks: サイン・イン


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。 プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。 お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

表示名をお選びください

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

(半角英数字で3文字以上31文字以下にする必要があります)


「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


この記事を評価する

コメント

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=SOA and Web services
ArticleID=245556
ArticleTitle=PerlでXML-RPCを始めよう 第2回:XML-RPC Middleware
publish-date=03012001
author1-email=jjohn@cs.umb.edu
author1-email-cc=

タグ

Help
このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。

スライダーバーを使用することで、より多く(少なく)タグを表示します。

人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。

マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。

このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。