BEARで始めるWebアプリケーション開発 その3「リソースを作ってみよう」

前回、BEARでのリソースの作り方まで分かったので、今回は実際にリソースを作ってみましょう。

リソースを設計する

リソースを実際に実装する前に、どんなリソースを作るか決めておきたいと思います。リソース指向の場合、先にリソース設計をきちんとやっておくと、後々Webアプリケーションを作るのが楽になるんじゃないかなと思います。

今回の"逆さ語"の場合、ユーザに提供したい機能は非常に明瞭かつシンプルです。

  • 与えられた文章を逆さ語に変換する

これだけですね。逆に、これ以外の機能はあってもいいけど、必須ではないという事になります。

という事で、リソースとしては、上記要件を満たすもの1つだけ作れば、今回作成したいWebアプリケーションのキモの部分ができあがる訳ですね。

続いて、もう少し具体的にリソースの定義をしておきます。リソース作成に必要な情報はだいたい以下の4つになります。

  • URI
  • CRUD各メソッドの処理内容
  • 出力表現の形式
  • 他のリソースとのリンク関係

リソース設計はかなり自由度が高くて色々な作り方ができるので、難しいところではあるんですが、逆に腕の見せ所とも言えます。

今回の例は比較的単純なものなので、誰がやっても同じになりそうなもんだと思うんですが、それでも例えば、

  • 文章をBODYに書いて"POST /sakasago"すると、変換された逆さ語のリソースが作成される
  • "PUT /sentences/{文章}"とすると、変換された逆さ語のリソースが作成される
  • "GET /sentence?s={文章}"とすると、変換された逆さ語を取得できる

などなど…色々なリソースの作り方のパターンが考えられます。

今回は、この中で3つ目の、パラメータとして文章を入れてGETしたら逆さ語が得られるという設計にしようと思います。

これは、「裏では毎回変換処理してるかもしれないし、キャッシュがあるかもしれない、もしかしたら外部のWebサービスを使ってるかもしれない」なんていう内部実装の事は一切気にする事なく、「とにかくGETしたら逆さ語が得られる」という(リソースの利用者側から見て)分かりやすい設計になる為です。こういうカプセル化ができるのが、リソース指向の大きなメリットですよね。

という事で、今回作るリソースは以下のようなものにしました。

URI
/sentence?s={文章}
CRUD各メソッドの処理内容
GETのみ。与えられた文章を逆さ語に変換する。
出力表現の形式
変換された逆さ語を返す。連想配列で、ひらがなとローマ字を返すようにする。
他のリソースとのリンク関係
無し

URIに関しては、個人的には"GET /sentences/{文章}"という形式がよいかと思ったんですが、BEARの場合、リソースのURIはそのまま"App/Ro"配下のディレクトリ構造にマッピングされる為、パス名の中に動的に変化する部分を含む事ができないとの事なので、文章はパラメータで渡す形にしました。*1

メソッドとしては今回はGETのみ用意すればオッケーで、表現形式として、変換された逆さ語をひらがなとローマ字の2つの形式で返したいので、それらを連想配列で返すようにします。

あと、BEARでは、他のリソースとのリンク関係も定義する事ができて、関連するリソースを芋づる式に読み込む事ができるという素晴らしい機能があるんですが、今回は他にリソースが無いのでこの機能は使用しません。

リソースを実装する

このぐらいまで設計しておけばリソースが実装できるかと思うので、早速リソースの実装に取り掛かります。

以降は、"sakasago"という名前のアプリケーションを、"/home/bear/sakasago"に作成済みという前提で話を進めます。

"/home/bear/sakasago/App/Ro/sentence.php"というファイルを作成して、以下のように記述します。

<?php
require_once dirname(__FILE__).'/Sakasago.php';

class App_Ro_Sentence extends BEAR_Ro
{
    /**
     * onRead
     *
     * @required s
     */
    public function onRead($values)
    {
        $lib_sakasago = new Sakasago();
        $sentence = $values['s'];
        if ( $lib_sakasago->convert($sentence) === false ) {
            throw $this->_exception('文章を変換できませんでした。',
                                    array(
                                          'code' => BEAR::CODE_ERROR,
                                          'info' => array(),
                                         )
                                   );
        }
        $result = array(
                        'kana' => $lib_sakasago->getConvertedSentence('kana'),
                        'roman' => $lib_sakasago->getConvertedSentence('roman'),
                       );
        return $result;
    }
}
?>

"Sakasago.php"というファイルは、実際に逆さ語のサービスで使用している変換処理を行うクラスファイルです。

実際には、onReadメソッド内にゴリゴリと処理内容を書く事になると思うんですが、今回は既にできあがったものがあったので、それを再利用する事にしました。

これで、リソースの実装は完了です。*2 ね、簡単でしょう?(笑)

では、実際にちゃんとリソースとして動くのか試してみましょう。

$ bear read sentence?s=逆さ語
code
200
header
Array
(
    [request] => Array
        (
            [uri] => sentence
        )

)
body
array (
  'kana' => 'おがさかす',
  'roman' => 'ogasakas',
)

きちんと動作していますね!

ここまでだと、以前作ったクラスファイルを再利用して、その処理がきちんと動作する事を確かめただけにしか見えないかもしれませんが、この「処理を"リソース"として定義した」という事は、実は非常に大きな意味を持ちます。

…といったところで、今回は時間切れです。続きは、また次回以降に…。

次回は?

次回は、リソースを利用する側である、"ページ"の作成に入っていきたいと思います。

*1:この点に関しては、私自身は"リソースのURIは設計者が自由に設定できるべき"と思っているので、mod_rewriteで静的URLを動的URLに変換するような、リソースのURIと実ファイルとのマッピング機能があってもいいんじゃないかなと思いました。

*2:エラーの返し方は、Wikiのリソースサンプルを参考にしましたが、これで良かったのかどうかは若干不安…。(^^;ゞ (追記:2010/01/27)マニュアルを整備して頂いたのでそちらを参考にしてエラー処理部分を修正しました。