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>
ふむ、なかなかよさげです。とあるプロジェクトのコードで試してみるとします。