BEARで始めるWebアプリケーション開発 その11「リソースをWebAPIとして外部に公開する」
今回は、リソースをWebAPI*1として外部に公開する為の方法について学びます。
リソースをWebAPIとして提供する場合、外部からはGETのみで、かつ返す表現がXML・JSONの場合は非常に簡単で、PageのonOutputハンドラでdisplayメソッドを使っていたところを、outputメソッドに変えるだけです。
<?php public function onOutput() { $this->output('xml'); //$this->output('json'); } ?>
BEARでは、リソースが値を返す時点では、表現を伴わない単なるデータ構造になっているので*2、状況に応じた表現の変更を極めて容易に行う事ができます。
この、表現形式を決めるアウトプットフィルタは自分で作る事もできて、"App/Resource/output"というディレクトリを作って、その中に"{形式名}.php"というファイル名でPHPファイルを作成すると、それを利用する事ができるようになります。
デフォルトで用意されているアウトプットフィルタは、PEARディレクトリ配下の"BEAR/Resource/output"の中にあります。デフォルトのアウトプットフィルタの動作を変えたい場合は、ここから"App/Resource/output"にコピーしてきて中身を書き換えてやれば、そちらが優先して使われるようになります。
今回は試しに、何らかの画像生成を行ってIMAGICKオブジェクトを返すリソースを作った時に、それを画像ファイルとしてHTTP出力するアウトプットフィルタを作ってみました。
<?php /** * イメージ出力 * * @param array $values 出力データ * @param array $options オプション(type:gif|jpeg|jpg|png , expire:有効期限) * * @return BEAR_Ro */ function outputImage($values, array $options) { $ro = BEAR::factory('BEAR_Ro'); $type = ( isset($options['type']) === true ) ? $options['type'] : 'png'; switch ( $type ) { case 'gif': $mime = 'image/gif'; break; case 'jpeg': case 'jpg': $mime = 'image/jpeg'; break; case 'png': $mime = 'image/png'; break; } $expire = ( isset($options['expire']) === true && $options['expire'] > 0 ) ? $options['expire'] : 0; $headers = array(); $headers['X-BEAR-Output: IMAGE'] = 'Content-Type: '.$mime; $headers[] = 'Expires: '.$expire; $headers[] = 'Last-Modified: '.gmdate('D, d M Y H:i:s ', time()).' GMT'; $headers[] = 'Cache-Control: public'; $headers[] = 'Pragma: '; $ro->setHeaders($headers); $ro->setBody(array_shift($values)); return $ro; } ?>
これを、"App/Resource/output/image.php"として作成しておいて、Pageファイルのアウトプットフィルタを以下のようにすると画像データを返すようになるので、imgタグのsrcとかで使えるようになります。
<?php public function onOutput() { $this->output('image', array('type' => 'png')); } ?>
今回は、リソース側で画像生成するような場合の想定でしたが、「リソース自体は普通に連想配列を返すけど、出力する時にその情報を利用して画像生成してHTTP出力する」*3なんていうアウトプットフィルタも簡単に作れる事が分かるかと思います。