Help language development. Donate to The Perl Foundation

Cro::RPC::JSON cpan:VRURG last updated on 2018-10-19



Cro::RPC::JSON - convenience shortcut for JSON-RPC 2.0


use Cro::HTTP::Server;
use Cro::HTTP::Router;
use Cro::RPC::JSON;

class JRPC-Actor is export {
    method foo ( Int :$a, Str :$b ) is json-rpc {
        return "$b and $a";

    proto method bar (|) is json-rpc { * }

    multi method bar ( Str :$a! ) { "single named Str param" }
    multi method bar ( Int $i, Num $n, Str $s ) { "Int, Num, Str positionals" }
    multi method bar ( *%options ) { [ "slurpy hash:", %options ] }

    method non-json (|) { "I won't be called!" }

sub routes is export {
    route {
        post -> "api" {
            my $actor =;
            json-rpc $actor;
        post -> "api2" {
            json-rpc -> Cro::RPC::JSON::Request $jrpc-req {
                { to-user => "a string", num => pi }


This module provides a convenience shortcut for handling JSON-RPC requests by exporting json-rpc function to be used inside a Cro::HTTP::Router post handler. The function takes one argument which could either be a Code object or an instantiated class.

When code object is used:

json-rpc -> $jrpc-request { ... }

sub jrpc-handler ( Cro::RPC::JSON::Request $jrpc-request ) { ... }
json-rpc -> &jrpc-handler;

it is supplied with parsed JSON-RPC request (Cro::RPC::JSON::Request).

When a class instance is used a JSON-RPC call is mapped on a class method with the same name as in RPC request. The class method must have is json-rpc trait applied (see SYNOPSIS example). Methods without the trait are not considered part of JSON-RPC API and calling such method would return -32601 error code back to the caller.

The class implementing the API is called JSON-RPC actor class or just actor.

If the only parameter of a JSON-RPC method has Cro::RPC::JSON::Request type then the method will receive the JSON-RPC request object as parameter. Otherwise params object of JSON-RPC request is used and matched against actor class method signature. If params is an object then it is considered a set of named parameters. If it's an array then all params are passed as positionals. For example:

params => { a => 1, b => "aa" }

will match to

method foo ( Int :$a, Str :$b ) { ... }


params => [ 1, "aa" ]

will match to

method foo( Int $a, Str $b ) { ... }

If parameters fail to match to the method signature then -32601 error would be returned.

To handle various set of parameters one could use either slurpy parameters or multi methods. In second case the is json-rpc trait must be applied to method's proto declaration.

NOTE that multi method cannot have the request object as a parameter. This is due to possible ambiguity in a situation when there is a match to one multi candidate by parameters and by the request object to another.




Vadim Belman


Artistic License 2.0

See the LICENSE file in this distribution.