GET、POST、PUT、DELETEの4つのメソッドを使い切ってリソースをコントロールしようというRESTfulな概念には賛同だけれども、 ブラウザがGET、POSTのみのサポートだよねぇ〜っていう状況はよくあります。 Ruby on Railsではそこまで深く調べてないけど、POSTメソッドのパラメータ「_method」に「DELETE」か「PUT」という値を入れることでもう二つのメソッドをサポートさせているように見せている?ようだ。
Perlで僕がいつも使っているWAF、MojoliciousではサーバサイドのルータでPUT、DELETEに対応しているので、 Railsで使っている「_method」フィールドを活用すればそれなりにRESTfulでありコントローラの記述も スッキリするんじゃないかと思う。 つまりディスパッチ前にうまいことフックさせて_methodの値でメソッドを書き換える。
よって以下のMojolicious::Liteのコードがうまく動いた。
#!/usr/bin/env perl
use Mojolicious::Lite;
app->hook(
before_dispatch => sub {
my $c = shift;
if($c->req->method eq 'POST' && $c->req->param('_method')) {
my $methods = [qw/GET POST PUT DELETE/];
if ( grep { $_ eq $c->req->param('_method') } @$methods ) {
$c->req->method( $c->req->param('_method') );
}
}
}
);
get '/' => sub {
my $self = shift;
$self->render('index');
};
del '/' => sub {
my $self = shift;
$self->render_text('DELETE resource!');
};
app->start;
__DATA__
@@ index.html.ep
<form action="/" method="post">
<input type="hidden" name="_method" value="DELETE" />
<input type="submit" value="DELETE" />
</form>
ふむ、なかなかよさげです。とあるプロジェクトのコードで試してみるとします。