@nqounetです。


追記(2014/08/16): Plack::App::*は、ただのアプリケーションを登録する名前空間ではない事を知りました。考え方によっては、JSON-RPCの機能を追加する、という事でもありますが、なにか違う気がするので、とりあえず非推奨という扱いにしました。

JSON::RPC::Liteは簡単に処理系を書きたいと思って作ったのですが、逆にJSON::RPC::Specからのアプローチで書いてみたらどうなるのかを確かめてみました。

Plack::App::JSONRPC

JSON::RPC::SpecにはHTTPサーバーとしての機能はないので、Plackを使って簡単なPSGIアプリを作ってみました。

要望からの実装と、機能からの実装がどのように違うのかも確認できた気がします。

newでmethodを渡せるようにしたので、処理系の書き方はLiteとそれほど変わりませんが、Plackの各機能を組み合わせて使えるので、より汎用的になりました。

例えば ‘/jsonrpc’ に対してこのアプリを設定してみると以下の様な感じで書けます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Plack::App::JSONRPC;
use Plack::Builder;

my $jsonrpc = Plack::App::JSONRPC->new(
methods => {
echo => sub { $_[0] },
empty => sub {''}
}
);
my $app = sub {
[200, ['Content-Type' => 'text/plain'], ['Hello']];
};
builder {
mount '/jsonrpc', $jsonrpc->to_app;
mount '/' => $app;
};

如何でしょうか?

内側の機能

Plack::App::JSONRPCを書くのに、Plackについて色々と調べていたのですが、よく言われているタマネギの機構が良いですね。

JSON::RPC::Specは、JSON文字列を解釈してエラーも良い感じに処理してJSON-RPCっぽいJSON文字列で返してくれるのですが、時々レスポンスをハッシュのまま加工したい、と思うことがあります。

テストの中では、レスポンスのJSON文字列をもう一度ハッシュに変換してから中身を確認しました。ハッシュの順序は確実に変わるので、文字列を単純に比較するとテストの結果が正しく得られません。

Plack::Middlewareのようにwrap機構を備えて、JSON文字列とPerlの変数の相互変換だけを扱う処理を作成すると、テストでも扱いやすくなりますね。