File Coverage

blib/lib/JSON/RPC/Dispatcher/App.pm
Criterion Covered Total %
statement 2 4 50.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 4 6 66.6


line stmt bran cond sub pod time code
1             package JSON::RPC::Dispatcher::App;
2             BEGIN {
3 1     1   686 $JSON::RPC::Dispatcher::App::VERSION = '0.0506';
4             }
5              
6 1     1   354 use Moose;
  0            
  0            
7             use JSON::RPC::Dispatcher;
8              
9             =head1 NAME
10              
11             JSON::RPC::Dispatcher::App - A base class for creating object oriented apps with JRD.
12              
13             =head1 VERSION
14              
15             version 0.0506
16              
17             =head1 SYNOPSIS
18              
19             Create your module:
20              
21             package MyApp;
22              
23             use Moose;
24             extends 'JSON::RPC::Dispatcher::App';
25              
26             sub sum {
27             my ($self, @params) = @_;
28             my $sum = 0;
29             $sum += $_ for @params;
30             return $sum;
31             }
32              
33             sub guess {
34             my ($self, $guess) = @_;
35             if ($guess == 10) {
36             return 'Correct!';
37             }
38             elsif ($guess > 10) {
39             confess [986, 'Too high.', $guess];
40             }
41             else {
42             confess [987, 'Too low.', $guess];
43             }
44             }
45              
46             __PACKAGE__->register_rpc_method_names( qw( sum guess ) );
47              
48             1;
49              
50             Then your plack F<app.psgi>:
51              
52             MyApp->new->to_app;
53              
54             =head1 DESCRIPTION
55              
56             This package gives you a base class to make it easy to create object-oriented JSON-RPC applications. This is a huge benefit when writing a larger app or suite of applications rather than just exposing a procedure or two. If you build out classes of methods using JSON::RPC::Dispatcher::App, and then use L<Plack::App::URLMap> to mount each module on a different URL, you can make a pretty powerful application server in very little time.
57              
58             =head1 METHODS
59              
60             The following methods are available from this class.
61              
62             =head2 new ( )
63              
64             A L<Moose> generated constructor.
65              
66             When you subclass you can easily add your own attributes using L<Moose>'s C<has> function, and they will be accessible to your RPCs like this:
67              
68             package MyApp;
69              
70             use Moose;
71             extends 'JSON::RPC::Dispatcher::App';
72              
73             has db => (
74             is => 'ro',
75             required => 1,
76             );
77              
78             sub make_it_go {
79             my ($self, @params) = @_;
80             my $sth = $self->db->prepare("select * from foo");
81             ...
82             }
83              
84             __PACKAGE__->register_rpc_method_names( qw(make_it_go) );
85              
86             1;
87              
88             In F<app.psgi>:
89              
90             my $db = DBI->connect(...);
91             MyApp->new(db=>$db)->to_app;
92              
93             =cut
94              
95             #--------------------------------------------------------
96              
97             =head2 register_rpc_method_names ( names )
98              
99             Class method. Registers a list of method names using L<JSON::RPC::Dispatcher>'s C<register> method.
100              
101             __PACKAGE__->register_rpc_method_names( qw( add subtract multiply divide ));
102              
103             =head3 names
104              
105             The list of method names to register. If you want to use any registration options with a particular method you can do that by passing the method in as a hash reference like so:
106              
107             __PACKAGE__->register_rpc_method_names(
108             'add',
109             { name => 'ip_address', options => { with_plack_request => 1 } },
110             'concat',
111             );
112              
113             =cut
114              
115             sub _rpc_method_names {
116             return ();
117             }
118              
119             sub register_rpc_method_names {
120             my ($class, @methods) = @_;
121             $class->meta->add_around_method_modifier('_rpc_method_names', sub {
122             my ($orig, $self) = @_;
123             return ($orig->(), @methods);
124             });
125             }
126              
127             #--------------------------------------------------------
128              
129             =head2 to_app ( )
130              
131             Generates a PSGI/L<Plack> compatible app.
132              
133             =cut
134              
135             sub to_app {
136             my $self = shift;
137             my $rpc = JSON::RPC::Dispatcher->new;
138             my $ref;
139             if ($ref = $self->can('_rpc_method_names')) {
140             foreach my $method ($ref->()) {
141             if (ref $method eq 'HASH') {
142             my $name = $method->{name};
143             $rpc->register($name, sub { $self->$name(@_) }, $method->{options});
144             }
145             else {
146             $rpc->register($method, sub { $self->$method(@_) });
147             }
148             }
149             }
150             $rpc->to_app;
151             }
152              
153              
154             =head1 LEGAL
155              
156             JSON::RPC::Dispatcher is Copyright 2009-2010 Plain Black Corporation (L<http://www.plainblack.com/>) and is licensed under the same terms as Perl itself.
157              
158             =cut
159              
160             1;