Hatena::Groupcatalyst

masaki@catalyst RSSフィード

Fork me on GitHub
 | 

2007-12-20

Catalyst::Controller::Resources の使い方

| 01:06 | Catalyst::Controller::Resources の使い方 - masaki@catalyst を含むブックマーク はてなブックマーク - Catalyst::Controller::Resources の使い方 - masaki@catalyst Catalyst::Controller::Resources の使い方 - masaki@catalyst のブックマークコメント

Catalyst で map.resources 的なことをするコントローラ - masaki@catalyst - Catalystグループの続き.ここんとこのコミットで,やりたいことが大体できるようになったのでまとめる.

Catalyst::Controller::Resources とは,railsmap.resources 相当のことができるコントローラで,現在 coderepos で開発中.

これを継承したコントローラで list, create, show, update, delete, post, edit というサブルーチンを書いておくと,これらを動的に Chained Action 化して,URIHTTP Method の組で対応させて呼ばれるという仕組み.

まず簡単な例.

package MyApp::Controller::User;
use base 'Catalyst::Controller::Resources';

# GET /user
sub list {
    my ($self, $c) = @_;
}

# POST /user
sub create {
    my ($self, $c) = @_;
}

# GET /user/{user_id}
sub show {
    my ($self, $c, $user_id) = @_;
}

# PUT /user/{user_id}
sub update {
    my ($self, $c, $user_id) = @_;
}

# DELETE /user/{user_id}
sub delete {
    my ($self, $c, $user_id) = @_;
}

# GET /user/new
sub post {
    my ($self, $c) = @_;
}

# GET /user/{user_id}/edit
sub edit {
    my ($self, $c, $user_id) = @_;
}

さらに /user/{user_id}/article/{article_id} のようにネストさせたいを場合は config の belongs_to に親コントローラ名を指定する.

package MyApp::Controller::Article;
use base 'Catalyst::Controller::Resources';

__PACKAGE__->config( belongs_to => 'User' );

# GET /user/{user_id}/article
sub list {
    my ($self, $c, $user_id) = @_;
}

# GET /user/{user_id}/article/{article_id}
sub show {
    my ($self, $c, $user_id, $article_id) = @_;
}

config で指定できる他のオプションは collection と member があり,これらはそれぞれコレクション,メンバリソース直下のアクションを指定できる.

package MyApp::Controller::User;
use base 'Catalyst::Controller::Resources';

__PACKAGE__->config(
    collection => { feed  => 'GET' },
    member     => { about => 'GET' },
);

# GET /user/feed
sub feed {
    my ($self, $c) = @_;
}

# GET /user/{user_id}/about
sub about {
    my ($self, $c, $user_id) = @_;
}

これに似たものに sub foo :ActionClass('REST') とすることで foo_GET, foo_POST, ... というサブルーチンにメソッドディスパッチをしてくれる Catalyst::Action::REST というのがある.

Catalyst::Action::REST では foo_GET などは単なるサブルーチンとして呼ばれる.一方 Catalyst::Controller::Resources では list も create も全部 Action になるので,例えば sub list :ActionClass('MyAction') のようにして ActionClass で処理をフィルタリングすることも可能なところに違いがある.

hide-Khide-K2007/12/21 13:21どもです。これ便利っすねー。
ところでPUTに対してGET editはあるのにDELETEに対して GET deleteがないのは本家に合わせた形でしょうか?
というかPUTとget editの使い分けが僕の意図してるのと違うのかな?

ikasam_aikasam_a2007/12/21 13:30基本的に本家に合わせてます.
PUT は「メンバリソースの更新」,GET edit は「メンバリソース更新のための編集用ページ表示」という使い分けですね.
本家合わせなので「メンバリソース削除のためのページ表示」endpoint は作ってません.あまり考えてなかったけどあった方が便利ですかね?

hide-Khide-K2007/12/21 13:37なるほど。てっきりPUT/DELETEを使えないブラウザの代替URLかと勘違いしてました。
そういった意味だとshow->deleteの流れで十分ですね。
RESTful Webサービスでも買って勉強しなおします><

 |