Hatena::Groupcatalyst

masaki@catalyst RSSフィード

Fork me on GitHub

2009-01-24

オーバーロード POST with Catalyst

| 00:38 | オーバーロード POST with Catalyst - masaki@catalyst を含むブックマーク はてなブックマーク - オーバーロード POST with Catalyst - masaki@catalyst オーバーロード POST with Catalyst - masaki@catalyst のブックマークコメント

<input type="hidden" name="x-tunneled-method" value="delete" />

Catalyst::Controller::Resources でオーバーロード POST を使いたい - Yet Another Hackadelic

rails みたいに _method=put って書きたいよって人はこちらを参考にどうぞ.

SummerSummer2011/12/28 06:04Super ecxtied to see more of this kind of stuff online.

syvbdlzsyvbdlz2011/12/28 19:50qDqP1U <a href="http://cuwqgtyxjpyw.com/">cuwqgtyxjpyw</a>

rdvvfmbxfrdvvfmbxf2011/12/29 00:46H1QQrI , [url=http://tnowqwsepoby.com/]tnowqwsepoby[/url], [link=http://zivzhiodulaf.com/]zivzhiodulaf[/link], http://dehavtdyrkdy.com/

vhmhvgvwgvavhmhvgvwgva2011/12/30 23:31amPmWo <a href="http://fusnnxadihir.com/">fusnnxadihir</a>

eqxasarwskeqxasarwsk2011/12/31 02:36ih6g7x , [url=http://jibhwicekrsa.com/]jibhwicekrsa[/url], [link=http://evjsbbzufwzp.com/]evjsbbzufwzp[/link], http://femksvlagyck.com/

トラックバック - http://catalyst.g.hatena.ne.jp/ikasam_a/20090124

2008-04-20

ROA と Catalyst

| 23:33 | ROA と Catalyst - masaki@catalyst を含むブックマーク はてなブックマーク - ROA と Catalyst - masaki@catalyst ROA と Catalyst - masaki@catalyst のブックマークコメント

ROA と Catalyst の関係について考えるために,まずは ROA の特性についてをまとめておく.

アドレス可能性 (Addressability)
アプリケーションのデータセットを参照可能なリソースとして URI を通じて公開すること.すべてのページ(=リソース)に一意なアドレスが存在すると,ページをブックマークしたり,他のページからリンクしたり,URI をメールで送信したりできる.このときリソースの URI は構造的で予測可能であることが望ましく,それによってクライアントはリソースを利用しやすくなるというメリットがある.
ステートレス性 (Statelessness)
すべての HTTP リクエストが完全に独立していること.クライアントが送信する HTTP リクエストは,サーバがそのリクエストを処理するのに必要な情報がすべて含められた自己記述的メッセージ (Self-Describing Messages) となる.アドレス可能性から見ると,ステートレス性とはサーバ状態もリソースであって独自の URI が割り当てられることである.ここでサーバ状態はアプリケーション状態とリソース状態に分類される.アプリケーション状態とはサーバがリクエストを処理するのに必要な情報で,例えば検索結果リソースへのクエリ (?q=xxx) だったりページング状態 (?start=10) などである.アプリケーション状態はクライアントで維持されるもので,もちろんクライアントごとに異なるものである.一方リソース状態はクライアント共通のもので,サーバに格納される.例えばアップロードして URI が割り当てられた画像リソースがあるとき,この画像は様々なクライアントから共通に取得できる.この画像がリソース状態であり,サーバに格納されるものである.
接続性 (Connectedness)
Roy Fielding が言う「アプリケーション状態エンジンとしてのハイパーメディア」のことで,簡単に言うとリソースがリンクを持つということ.ハイパーメディアとは一般にハイパーリンクとフォームのことで,ユーザがハイパーリンクをたどるかフォームに記入するだけで別の状態へ移行,すなわちアプリケーション状態を遷移させる.Web が使いやすい要因の一つは,例えばユーザが設定した「ホームページ」から検索フォームやカテゴリのリンクによって様々に移動できるよう,Web 上のリソースが接続されているから.
統一インターフェイス (Uniform Interface)
HTTP メソッドを GET/POST/PUT/DELETE で CRUD 操作というように同じ方法で使用する.POST は従属リソースあるいは従属情報の作成に用いるものであるが,現実には特定のデータを処理するための汎用メソッドとして使われている.この使い方をオーバーロード POST と呼ぶが,これによってメソッド情報が HTTP メソッドから欠落し,統一インターフェイスではなくなってしまう.

さて,この中で「接続性」を満たすにはリソース表現に適切なリンクを含めるように設計する必要がある.そしてこれはサービス実装者が提供する View (HTML, XML, JSON, Atom, ...) において適切なリンクを含めるようにすることで満足されるため,Catalyst 特有の何かがあるわけではないと考える.

「統一インターフェイス」を満足して Catalyst でアプリケーションを作成するには

  • GET/POST/PUT/DELETE によって適切に処理を行うようアプリケーションを実装する.
  • かつ,特定のメソッドをサポートしないクライアントには代替手段を提供する.
    • このとき Catalyst 側から見て,代替手段を用いたときと本来のメソッドとの間でアクションが違うと面倒なので,吸収できることが望ましい.

というあたりを押さえる必要がある.このうち特定メソッドの代替手段とその吸収については,統一インターフェイスと PUT and DELETE tunneled POST パターン - masaki@catalyst - Catalystグループ にある方法で解決する.また HTTP メソッドによって適切に処理を切り替えるようにコントローラを作るには,Catalyst::Controller::ResourcesCatalyst::Controller::Resources の使い方 - masaki@catalyst - Catalystグループ)を使うか,あるいは Catalyst::Action::REST を使うという選択肢がある.

「アドレス可能性」と「ステートレス性」に関しては,やはりリソースの名前 (URI) を適切に考慮してコントローラを設計する必要がある.Catalyst では今時の WAF らしく URI とコントローラアクションがマッピングされる仕組みになっているから,URI を構造的に組み立てた上でそれに合わせたコントローラを作っていくという方法が取れる.この場合も Catalyst::Controller::Resources を使うと構造的なコントローラを比較的容易に作ることができる.

なお,リソースの表現という重要な概念に関しては別途言及する.

bqjelofhbqjelofh2011/03/23 22:36eMbc4S <a href="http://lrsrbvtvtazm.com/">lrsrbvtvtazm</a>, [url=http://pyikncyuaoto.com/]pyikncyuaoto[/url], [link=http://bulrykwoioob.com/]bulrykwoioob[/link], http://gvzfyolqkibh.com/

トラックバック - http://catalyst.g.hatena.ne.jp/ikasam_a/20080420

2008-04-19

統一インターフェイスと PUT and DELETE tunneled POST パターン

| 02:42 | 統一インターフェイスと PUT and DELETE tunneled POST パターン - masaki@catalyst を含むブックマーク はてなブックマーク - 統一インターフェイスと PUT and DELETE tunneled POST パターン - masaki@catalyst 統一インターフェイスと PUT and DELETE tunneled POST パターン - masaki@catalyst のブックマークコメント

HTTP の場合,統一インターフェイスとは HTTP メソッドのことで,特に一般的な操作に対して以下の4つが規定されている.

  • GET - リソースの表現を取得する
  • POST - リソースを作成する
  • PUT - リソースを変更する
  • DELETE - リソースを削除する

ROA 的にはこのような決まったインターフェイスでリソースの操作をするといいわけだが,Web アプリケーションの場合相手になるクライアントは(主に)Web ブラウザで,これが往々にして PUT/DELETE などをサポートしていないため,そのようなメソッド相当の処理も全部 POST で行うという現状がある.

ここで,Web アプリケーションというより Web システムという概念で考えると,クライアントは Web ブラウザだけではなく例えば PUT/DELETE もサポートしている専用クライアントということもあり得る.そうなると Web システムでは,PUT リクエストまたは PUT 相当にするために何らかのパラメータを付けた POST リクエストも同じアクションで扱える方がスマートだ.

Catalyst の場合も同様に,PUT tunneled POST リクエストはアクション判定と起動前に PUT に置き換えてしまうのが一番楽な方法になる.

rails を参考にすると,_method というパラメータ付きの POST リクエストの場合は,リクエストメソッドを _method パラメータの値にするという処理が行われている.これを Catalyst に持ってくるとこんな感じになる.

sub prepare_action {
    my $c = shift;

    if (exists $c->req->params->{_method} and $c->req->method eq 'POST') {
        $c->req->method(lc $c->req->params->{_method});
    }

    $c->NEXT::prepare_action(@_);
}

前置きが長かったけど,こんなちょっとしたことでもやるのとやらないのでは,コントローラの設計に結構響いたりするから怖い.

Catalyst REST Practice #0

| 01:13 | Catalyst REST Practice #0 - masaki@catalyst を含むブックマーク はてなブックマーク - Catalyst REST Practice #0 - masaki@catalyst Catalyst REST Practice #0 - masaki@catalyst のブックマークコメント

リソース指向アーキテクチャ (ROA) の特性は以下の4つ.

  • アドレス可能性 (Addressability)
  • ステートレス性 (Statelessness)
  • 接続性 (Connectedness)
  • 統一インターフェイス (Uniform Interface)

これらの特性や,ROA の核であるリソースにおける

  • リソースの名前
  • リソースの表現
  • リソース間のリンク

を実現するために Catalyst からどのようなアプローチが取れるかを考えたい.

ちなみに接続性というのは簡単に言うとリンクを持つということで,リソース間のリンクというのはその接続性のもとであるリソース(表現)に他のリソースへのリンクを持つということ.なのでこれらはリソース表現がリンクを持つように設計するべし,という指針であるので Catalyst でどうするかという話はしない.

Controller::Resources 0.03 released

| 00:36 | Controller::Resources 0.03 released - masaki@catalyst を含むブックマーク はてなブックマーク - Controller::Resources 0.03 released - masaki@catalyst Controller::Resources 0.03 released - masaki@catalyst のブックマークコメント

typesterさんのコミットからちょっと変更したけど,おかげさまで deep namespace サポートできたので CPAN にあげた.

ただ,その後で MANIFEST 変更してなかったために新しいテストファイルが付いていないことに気がついた.失態.

まぁともかくこんな事ができるようになりました.

package MyApp::Controller::API::Items;
use base 'Catalyst::Controller::Resources';

# GET /api/items/{item_id}
sub show {
    my ($self, $c, $item_id) = @_;
}

こいつに更にネストさせるのもできます.

package MyApp::Controller::API::Items::Orders;
use base 'Catalyst::Controller::Resources';

__PACKAGE__->config( belongs_to => 'API::Items' );

# GET /api/items/{item_id}/orders/{order_id}
sub show {
    my ($self, $c, $item_id, $order_id) = @_;
}
トラックバック - http://catalyst.g.hatena.ne.jp/ikasam_a/20080419