MVCフレームワークにおける Web API 実装

ちょっと前に miyagawa さんが 12 Things I dislike with Sledge という(数字で始まる Web つーぽいんとおーチックなタイトルで) Sledge の次期バージョンへの要望なんかを書いてます。この中で

10. REST な API や Basic 認証、XML-RPCAtom などをうまく処理できない

と、Sledge における Web API (XML-RPC/AtomPP) のハンドリングについての言及がありました。これからの MVC フレームワークに求められる必要条件の一つとしてこの Web API を処理しやすいかどうかというのは重要な気がします。

フレームワークに Web API 用の API が載っていて、その扱いが容易かつプロトコルの実装を知らなくても使えるようなアーキテクチャになっていると、開発者が Web API を公開するための敷居が下がり、自然とそのアプリケーションは外に開かれたアプリケーションとして構築されていくことでしょう。

実際、はてなフレームワークも今のところ Web API をうまく処理するための仕組みなんかは直接持っていないので、フレームワークを Hack するような感じでそれを実現してます。もう少し汎用化して開発者への負担を減らしたいなと思っています。

そんな折、CPANCatalyst::Plugin::XMLRPC が update されているのをたまたま見かけました。

Catalyst::Plugin::XMLRPC の使い方は SYNOPSIS にあるように

# include it in plugin list
use Catalyst qw/XMLRPC/;

# Public action to redispatch
sub entrypoint : Global {
    my ( $self, $c ) = @_;
    $c->xmlrpc;
}

# Methods with Remote attribute in same class
sub echo : Remote {
    my ( $self, $c, @args ) = @_;
    return join ' ', @args;
}

sub add : Remote {
    my ( $self, $c, $a, $b ) = @_;
    return $a + $b;
}

とコントローラに書く、ということでその扱いがとても楽。アプリケーション開発者は XML-RPC の仕様をほとんど意識せずに Perl でロジックを実装すればよい、という感じ。こんな風に Web API が実装できると、あとは Model でロジックを非 API 部分と共通になるように吸収してやるとか、Facade を用意することだけを考えるだけで済みます。

Plugin の中の実装は、例によって Perl の attribute を使い、XML-RPC のメソッドを Remote attribute がつけられているものに $c->xmlrpc で redispatch するようなことをやっています。プラグインでこのあたりが記述できるように CatalystAPI の構成がうまく設計されているあたりにセンスを感じます。

AtomPP に関しては typester さんによる Catalyst::Plugin::AtomPP などがあります。Catalyst::Plugin::XMLRPC の実装を参考にしているようです。REST に合わせて GET/POST/PUT/DELETE それぞれを prefix にしたメソッドに redispatch するような実装になってます。

という感じで Lightweight なフレームワークにおける Web API の実装というのをいろいろみてると面白い感じ。Rails のあたりを誰か解説してくれりんこ。