BEAR.Sundayを触ってみたメモ (2)はじめてのアプリケーションリソース
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ということです。
内部APIがURIを持ち、リクエストとレスポンスを構成することで、サーバーサイドに擬似的な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ディレクトリを追加して phpunitとphpunit.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