読者です 読者をやめる 読者になる 読者になる

k-holyのPHPとか諸々メモ

Webで働くk-holyがPHP(スクリプト言語)とか諸々のことをメモしていきます。ソースコードはだいたいWindowsで動かしてます。

BEAR.Sundayを触ってみたメモ (2)はじめてのアプリケーションリソース

PHP BEAR

BEAR.Sundayを触ってみたメモ (1)インストール の続きです。

2つ用意されているチュートリアルのどちらにしようか考えましたが、DBありきではなく簡単なアプリケーションリソースの作成からやった方が、リソース指向を謳うBEARらしいかなと思い、"はじめての"チュートリアル をやってみます。

まずは、はじめてのリソース
http://code.google.com/p/bearsunday/wiki/my_first_resource

アプリケーションリソース

ここれではnameを渡すと挨拶を返してくれるgreetingリソースをつくってみます。 MVCでいうとモデルにあたる部分のアプリケーションリソース(appリソース)です。アプリケーションの内部APIとして利用されます。

http://code.google.com/p/bearsunday/wiki/my_first_resource

リソースはURIとRESTインタフェースを持っており、レイヤによってページリソースとアプリケーションリソースの2つに分かれるようです。
それぞれ担当するレイヤが異なっていて、前者がいわゆるページコントローラに相当し、後者は内部APIということです。
内部APIURIを持ち、リクエストとレスポンスを構成することで、サーバーサイドに擬似的なHTTPを構築するようなイメージでしょうか。

考えてるといつまで経っても触れなくなりそうなので、とりあえず先に進みます。

Greetingリソース

URI app://self/first/greeting?name=名前
クラス名 sandbox\Resource\App\First\Greerting
ファイル apps/sandbox/Resource/App/First/Greeting.php

すでに用意されているものを、手順通りCLIから呼んでみます。

以下、msysgit 1.7.11のGit Bashにて

$ PATH=/c/php:$PATH
$ cd apps/sandbox/htdocs
$ php api.php get app://self/first/greeting
400 Bad Request
x-exception-class: BEAR\Resource\Exception\InvalidParameter
x-exception-message: $name in sandbox\Resource\App\First\Greeting::onGet
x-exception-code: 0
x-exception-file-line: C:\Users\k_horii\Dropbox\Documents\Projects\BEAR\BEAR.Sunday\vendor\BEAR\Resource\src\BEAR\Resource\Invoker.php:237
x-exception-previous: -
x-exception-id: eee903
cache-control: no-cache
date: Wed, 18 Jul 2012 08:08:39 GMT
content-type: text/html; charset=UTF-8
[BODY]
Internal error occured (eee903)

エスケープシーケンスが効いてなくて寂しいですが、とりあえず結果は手本通り返ってきています。
クエリパラメータ name が足りないため、ステータス400が返されており、リソースへのリクエストで発生した例外の情報が x-exception-*** というヘッダで返されています。
例外クラスが BEAR\Resource\Exception\InvalidParameter で、メッセージが $name in sandbox\Resource\App\First\Greeting::onGet と分かります。

nameパラメータを指定してみます。

$ php api.php get app://self/first/greeting?name=BEAR
$ php api.php get app://self/first/greeting?name=BEAR
200 OK
cache-control: no-cache
date: Wed, 18 Jul 2012 08:17:41 GMT
content-type: text/html; charset=UTF-8
[BODY]
"Hello, BEAR"

ステータス200とともに、Greetingリソースクラスの onGet() メソッドで定義された内容が、ボディとして返されています。

手本通り、GreetingリソースのonGet()メソッドを書き換えてみます。

$ php api.php get app://self/first/greeting?name=BEAR
200 OK
cache-control: no-cache
date: Wed, 18 Jul 2012 08:21:14 GMT
content-type: text/html; charset=UTF-8
[BODY]
"Hello, BEAR"

期待通り、同じレスポンスが返されました。


次は、ビルトインサーバを使ったWeb API
http://code.google.com/p/bearsunday/wiki/my_first_web_api

以下の内容で、sandboxアプリケーションのWebAPIをビルトインサーバで起動するためのショートカットを作成します。
リンク先 C:\php\php.exe -S localhost:8099 api.php
作業フォルダ C:\Users\k_horii\Dropbox\Documents\Projects\BEAR\BEAR.Sunday\apps\sandbox\htdocs

ビルトインサーバを起動して、ブラウザからアクセスしてみます。
http://localhost:8099/first/greeting?name=BEAR

"Hello, BEAR"

アプリケーションリソースをWebからアクセスすると、body部分が表示されるようです。


次は、リソーステスト
http://code.google.com/p/bearsunday/wiki/my_first_test

以下のテストクラスファイルがすでに用意されています。
apps/sandbox/tests/Resource/App/First/GreetingTest.php

なんだかWiki記載の内容と微妙に違いますが、とりあえずこのまま進めてみます。

Git Bashにて

$ phpunit tests/Resource/App/First/GreetingTest.php
Parse error: syntax error, unexpected T_USE, expecting T_FUNCTION in C:\Users\k_horii\Dropbox\Documents\Projects\BEAR\BEAR.Sunday\apps\sandbox\App.php on line 25

PHP5.4にはPHPUnitはおろか、PEARすら入れてないんでした…(XAMPPのphpにあるphpunitコマンド経由でphp5.3が呼ばれてる)
めんどくさいので、かなり反則っぽいですが、include_pathにxamppのpearディレクトリを追加して phpunitphpunit.batをC:\xampp\phpからc:\phpにコピーして、中身のパスを書き換えました。

$ phpunit tests/Resource/App/First/GreetingTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from C:\Users\k_horii\Dropbox\Documents\Projects\BEAR\BEAR.Sunday\apps\sandbox\phpunit.xml.dist

...

Time: 4 seconds, Memory: 6.00Mb

OK (3 tests, 3 assertions)

Writing code coverage data to XML file, this may take a moment.

Generating code coverage report, this may take a moment.

テストが通りました!

カバレッジレポート

build/coverage/index.htmlにはどの範囲のコードが今のテストでカバーできたら確認することができます。

http://code.google.com/p/bearsunday/wiki/my_first_test

phpunit.xml.dist の設定に従って、apps\sandbox\build\coverage\index.html phpunit実行時に作成されるみたいです。
どれどれ…

わおぉ!!(すみません、こういうの見るの初めてで…)

サンプルと一ヶ所違う部分があったのが気になりましたが、このメソッドはテスト対象ではないようです。

    /**
     * Renderable ?
     *
     * @depends resource
     * test
     */
    public function render($resource)
    {
        $html = (string) $resource;
        $this->assertInternalType('string', $html);
    }

リソースオブジェクトの文字列表現(HTML?)が取得できるかどうか、というテストのようですが…。

アノテーションの部分を @test に修正してみたところ、テストは通ったものの、以下のような例外が発生しました。

'BEAR\Framework\Exception\TemplateNotFound' with message 'C:\Users\k_horii\Dropbox\Documents\Projects\BEAR\BEAR.Sunday\apps\sandbox\Resource\App\First\Greeting.tpl'
 in C:\Users\k_horii\Dropbox\Documents\Projects\BEAR\BEAR.Sunday\package\BEAR\Framework\src\BEAR\Framework\Module\TemplateEngine\SmartyModule\SmartyAdapter.php:93

テンプレートファイルがないというエラーです。
リソースオブジェクトが__toString()された時、同一階層に拡張子.tplのファイルを探しに行く仕組みなのでしょうか。

空のファイルを設置して再度テストを実行してみたところ、今度は以下のような結果に。

There was 1 failure:

1) sandbox\tests\Resource\App\Blog\GreetingTest::body
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
-Hello, BEAR
+

C:\Users\k_horii\Dropbox\Documents\Projects\BEAR\BEAR.Sunday\apps\sandbox\tests\Resource\App\First\GreetingTest.php:65
C:\php\phpunit:46

リソースのbodyのテストに失敗しています。

テンプレートファイルにHello, BEARと書いて再度テストしてみます。

$ phpunit tests/Resource/App/First/GreetingTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from C:\Users\k_horii\Dropbox\Documents\Projects\BEAR\BEAR.Sunday\apps\sandbox\phpunit.xml.dist

....

Time: 2 seconds, Memory: 7.75Mb

OK (4 tests, 4 assertions)

Writing code coverage data to XML file, this may take a moment.

Generating code coverage report, this may take a moment.

ビンゴでした。
テンプレートファイルがあればそれを使った出力結果がリソースオブジェクトのボディにもセットされるということでしょうか。


とりあえず、今回はここまで。
次回はページリソースによるテンプレートを使った出力と、BEARならではの機能、ページリソースからアプリケーショリソースへのリクエストを試してみようと思います。

BEARのリソース(アプリケーションリソース、ページリソース)を理解する上で、こちらのBEAR Blogの記事が参考になります。
BEAR.Resource « BEAR Blog