ブログ  前の記事  次の記事  2008-03-11 

たけまる / Catalyst::Controller::Atompub - コレクション URI の変更


2008-03-11

_ Catalyst::Controller::Atompub - コレクション URI の変更 [atompub][perl]

(追記) 情報が古くなってますので [2008-04-10-1] を参考にしてください

ZIGOROu さんから,Catalyst::Controller::Atompub でコレクション URI
を変更する方法について相談を受けました.

Catalyst::Controller::Atompubのdispatch、Slugヘッダとか - Yet Another Hackadelic

結論としては,ZIGOROu さんが自力で解決されたので僕が出る幕はない
のですが,いくつか修正とまとめをしておきます.

Catalyst::Controller::Atompub は,コレクション URI と Controller
クラスが 1:1 に対応するという前提で作られています.

たとえば,次のようにしてコレクション Controller を作成します.
package MyApp::Controller::Collection;
use base qw(Catalyst::Controller::Atompub::Collection);

すると,URI は /collection になります.このコレクションにエントリを
追加 (POST) すると,新しく作成される URI は/collection/<entryID> の
ようになります.つまり,/collection という URI でコレクションを表
します.

コレクション /collection
メンバ (エントリなど) /collection/<entryID>

■ ユーザ別コレクション: /collection/<userID>

ZIGOROu さんがやりたかったことは,コレクション URI を
/collection/<userID> のようにすることでした.つまり,コレクション
URI をユーザごとに動的に変更したいということです.

いくつかやり方はありそうですが,ZIGOROu さんの方法が一番簡単そうな
ので,改めて紹介します.次のようにして,default と edit_uri メソッ
ドを上書きしてください.それぞれにマッチする条件を LocalRegex 属性
で指定するのがポイントです.

package MyApp::Controller::Collection;

use NEXT;
use base qw(Catalyst::Controller::Atompub::Collection);

sub edit_uri :LocalRegex('^(\w+)/(\w+)') {
    my ($self, $c) = @_;
    $self->NEXT::edit_uri($c);
}

sub default :LocalRegex('^(\w+)') {
    my ($self, $c) = @_;
    $self->NEXT::default($c);
}

これで,コレクション URI は /collection/<userID> に変更されます.ま
た,エントリ URI は /collection/<userID>/<entryID> になります.

コレクション /collection/<userID>
メンバ (エントリなど) /collection/<userID>/<entryID>

<userID> を取得するときは $c->req->captures->[0] としてください.

なお,ZIGOROu さんの例では,default メソッドを先に定義していますが,
探索順の関係から edit_uri を先にしてください (default が edit_uri
より先にマッチしてしまうので).また,$c->NEXT::default ではなく
$self->NEXT::default が正しいです.

CRUD 処理は,do_create のような名前のメソッドに実装してもかまいませ
んが,C::C::Atompub のセオリー通りに ":Atompub" 属性を持ったメソッ
ドでも OK です.

sub create_entry :Atompub('create') {
    # implements
}

■ プラトニック URI: /collection{.atom|.json|.html}

他にも同様の例はあります.たとえば,URI によって提供するリソースの
表現形式を変更したい場合があります./collection にアクセスがあった
ときは XML フィードを返すけれど,/collection.json では JSON,
/collection.html では HTML を返すという具合です.

次のようにすると,コレクション URI に拡張子を付けることができます.

package MyApp::Controller::Collection;

use NEXT;
use base qw(Catalyst::Controller::Atompub::Collection);

sub edit_uri: Regex('^collection/(\w+)(\.\w+)?') {
    my ($self, $c) = @_;
    $self->NEXT::edit_uri($c);
}

sub default :Regex('^collection(\.\w+)?') {
    my ($self, $c) = @_;
    $self->NEXT::default($c);
}

コレクション /collection{.atom|.json|.html}
メンバ (エントリなど) /collection/<entryID>{.atom|.json|.html|.xxx}

RESTful Web サービス 4.6.1 によれば,プラトニック URI (拡張子のない
URI) を提供しておき,拡張子などに合わせて表現を変更するのは良いプラ
クティスだそうです.



ikasam_a が URI::Platonic というモジュールを作ってくれていますので,
よかったらどうぞ (CPAN ではなく CodeRepos にあります).

URI::Platonic を Decorator として動作するようにしてみた - masakiのはてなダイアリー

一言メッセージをこっそり送信できます (非公開)
 今年の西暦→