ウェブサービスとは ネットワーク越しに、マシン同士の相互運用性をサポートする仕組みのことです。 ウェブアプリケーションにおいては、多くの場合インターネットを介して、 リモートホストから呼び出して利用できるAPI群をウェブサービスと呼びます。
たとえば、Flex-basedクライアントはサーバで動いている、PHPのウェブアプリケーションに実装された関数を呼び出すことがあります。 ウェブサービスはコミュニケーションプロトコルスタックの基礎部分をSOAP に依存しています。
YiiはCWebService と CWebServiceActionを提供することで、 ウェブアプリケーションでウェブサービスを提供する作業を簡単にします。 APIはサービスプロバイダと呼ばれるクラス群にまとめられます。 Yiiはそれぞれのクラスについて、WSDLスペックファイルを生成し、 どのAPIが利用可能で、どのように呼び出すことができるのかを記述します。
クライアントによってAPIが呼び出されると、Yiiが対応するサービスプロバイダをインスタンス化し、 要求されたAPIを実行することで、リクエストを完了します。
注意: CWebService は PHP SOAP extension に依存します。 このセクションの例を実行する前に拡張が有効になっていることを確認して下さい。
上で述べたように、サービスプロバイダとはリモートから呼び出し可能なメソッドを定義するクラスのことです。
Yiiはdoc comment と class reflection に基づいて、 どのメソッドがリモートから呼び出し可能であり、どのような引数をとり、そしてどのような返り値を返すのかを決定します。
まず単純な株価情報サービスからはじめましょう。
このサービスではクライアントが株価情報を要求できます。
サービスプロバイダを以下のほうに定義します。
プロバイダクラスのStockController
を、 CControllerのサブクラスとして定義していることに注意してください。
これは必須ではありませんが、後ほどなぜこうするのか理由を説明します。
class StockController extends CController
{
/**
* @param string the symbol of the stock
* @return float the stock price
* @soap
*/
public function getPrice($symbol)
{
$prices=array('IBM'=>100, 'GOOGLE'=>350);
return isset($prices[$symbol])?$prices[$symbol]:0;
//... $symbol の株価を返す
}
}
上記の例では、getPrice
というメソッドを宣言し、コメントに@soap
タグをつけることで、
ウェブサービスAPIにしています。
コメントによって引数のデータタイプと返り値も決まります。
追加のAPIも同じ方法で宣言できます。
サービスプロバイダを定義したので、クライアントから呼び出し可能にする必要があります。
今回の例では、コントローラのアクションをサービスとして公開したいと思います。
これはコントローラで、CWebServiceActionアクションを宣言することで容易に実現可能です。
サンプルコードではStockController
に追加します。
class StockController extends CController
{
public function actions()
{
return array(
'quote'=>array(
'class'=>'CWebServiceAction',
),
);
}
/**
* @param string the symbol of the stock
* @return float the stock price
* @soap
*/
public function getPrice($symbol)
{
//...$symbol の株価を返す
}
}
これがウェブサービスを作るのに必要なことすべてです!
URL http://hostname/path/to/index.php?r=stock/quote
にアクセスすれば、
今定義したウェブサービスのWSDLを表すXMLが表示されます。
ヒント: デフォルトでは、 CWebServiceAction はそのメソッドを含むコントローラを サービスプロバイダとみなします。これが
getPrice
メソッドをStockController
クラスに定義した理由です。
この例を完成させるために、できたばかりのウェブサービスを利用するクライアントを作ってみましょう。
例のクライアントはPHPで書かれていますが、Java
, C#
, Flex
などのその他の言語で書くこともできます。
$client=new SoapClient('http://hostname/path/to/index.php?r=stock/quote');
echo $client->getPrice('GOOGLE');
このスクリプトをブラウザか、コンソールで実行します。
結果として、GOOGLE
の株価350
が表示されます。
リモートから呼び出し可能なクラスメソッドとプロパティを定義する際に、 入出力パラメータのデータ型を決める必要があります。 以下のような基本データ型が利用可能です。
xsd:string
に対応します;xsd:int
に対応します;xsd:float
に対応します;xsd:boolean
に対応します;xsd:date
に対応します;xsd:time
に対応します;xsd:dateTime
に対応します;xsd:string
に対応します;xsd:struct
に対応します;xsd:anyType
に対応します.上記の基本型に当てはまらない場合は、複数の属性からなる複合型とみなされます。
複合型はクラスで表されます。各属性はクラスのパブリックプロパティのうち、
コメントで@soap
マークがついたものになります。
また、基本型や複合型の末尾に []
をつけることで配列を使うこともできます。
これは特定の型の配列を示します。
以下はPost
オブジェクトの配列を返すgetPosts
ウェブAPIの例です。
class PostController extends CController
{
/**
* @return Post[] a list of posts
* @soap
*/
public function getPosts()
{
return Post::model()->findAll();
}
}
class Post extends CActiveRecord
{
/**
* @var integer post ID
* @soap
*/
public $id;
/**
* @var string post title
* @soap
*/
public $title;
}
複合型のデータをクライアントから受け取るためには、 WSDL型からPHPクラスへの対応を宣言する必要があります。 これはCWebServiceActionのclassMapプロパティをを設定することで 実現されます。
class PostController extends CController
{
public function actions()
{
return array(
'service'=>array(
'class'=>'CWebServiceAction',
'classMap'=>array(
'Post'=>'Post', // or simply 'Post'
),
),
);
}
......
}
サービスプロバイダで IWebServiceProvider インターフェイスを実装することで、 リモートからのメソッド呼び出しを、実行前に横取りすることができます。 IWebServiceProvider::beforeWebMethod内でプロバイダは CWebService のインスタンスをうけとり、 CWebService::methodNameによって、リクエストされたメソッド名を得ることができます。 何らかの理由でリモートからのメソッド呼び出しを許可したくない場合は、false を返すことで実行を中断できます。 (例:認証が必要なアクセス)
Signup or Login in order to comment.