JSON::RPC::Liteというモジュールを書きました

@nqounetです。
JSON::RPCというJSON-RPCのPerlモジュールがあるのですが、これを使っているともっと簡単に書きたい、という気持ちになってきたので、簡単に書けるようなモジュールを作りました。

JSON-RPCとは

最近、JSONでクライアントとサーバーのやりとりをすることが多くなってきたので、どうせならなにか規格っぽいのがないかと探してみたところ、JSON-RPCというのがありました。

まあ、素人が考えるよりもいいだろうということで使ってみることにしました。

サーバー側の方を探してみたところ、PSGI仕様のそのままズバリな名前のモジュールJSON::RPCがあったので、これを使いました。

JSON::RPC::Lite

サーバーを動かすまではとても簡単だったのですが、必要な処理を書こうとすると結構面倒な気持ちになってきました。

処理の振り分けにRouter::Simpleを使っていたので、例えばMojolicious::Liteのように書けるようにしてみよう、ということで作ったのがJSON::RPC::Liteです。

ちなみに、書き方はLiteですが、実質はJSON::RPCのラッパーなので軽くはありません。

動かしてみる

ごく簡単に、その辺にありそうな感じで書けます。

1
2
3
4
5
6
7
8
use JSON::RPC::Lite;

method 'echo' => sub {
    my ($param) = @_;
    return $param;
};

as_psgi_app;

このファイルを app.psgi として保存したら、plackupでサーバーが起動します。

1
$ plackup app.psgi

そうすると、http://localhost:5000にサーバーができるので、クライアントから例えば以下のようなJSONをPOSTで送ってみます。

1
{"jsonrpc":"2.0","method":"echo","params":"Hello!","id":1}

すると、サーバーからJSONでレスポンスが返ってきます。

1
{"id":1,"jsonrpc":"2.0","result":"Hello!"}

実行のタイミングによって項目の順序は変わりますが、オブジェクトとして考えれば同じなので、実質的には問題無いと思います。

GitHubで公開していますので、よろしければ使ってみてください。

ちなみに、サーバーにJSONを送るときは、ChromeのアプリでDHCというのを使っています。

履歴も残る(もちろん再利用も簡単)し、見やすいようにフォーマットしてくれるので気に入っています。

JSON-RPCの実装

JSON-RPCのPerlによる実装は、実は結構あります。

仕様的に最適なのはJSON::RPC2だと思うのですが、コードの書き方が難しく、私には使いこなせませんでした。

JSON::RPCは、methodparamsから結果を返すという機構がシンプルで良いのですが、Dispatchが面倒でした。

今回欲しかったのは、paramsをそのまま引数にできる関数で、かつ、その近辺で発生したエラーについてもうまく処理してくれるものだったのですが、そんな都合の良いモノはありませんでした。

それ以外の処理も、欲しい部分はほとんどがJSON::RPC::Dispatch::handle_psgiに書かれていたので、乗っかることにしました。

まあ、単純に$matched->{code}が存在する場合は、それで実行する、というだけの機能を追加し、存在しなくなった$handlerを渡さないようにしただけです。

JSON::RPC::Dispatch::handle_psgiにあっても害はない機能だとは思いますが、とりあえず、こっちもLiteにしました。

本当はWebSocketでやりたかった

普通にパラメーターから関数を呼び出して値を返すだけなら、JSON-RPCではなく、RESTなAPIで充分なのですが、当初WebSocketでも使えるようなものを探していたので、JSON-RPCにたどり着きました。

ただ、先程も書いたとおり、エラー処理などを含めた丁度欲しい部分のモジュールがなく、それを書いたとしてもほぼJSON::RPC::Dispatch::handle_psgiと同じになるのが悩ましいですね。

comments powered by Disqus
Hugo で構築されています。
テーマ StackJimmy によって設計されています。