File Coverage

blib/lib/JSON/RPC/Dispatcher/App.pm
Criterion Covered Total %
statement 10 22 45.4
branch 0 4 0.0
condition n/a
subroutine 4 7 57.1
pod 2 2 100.0
total 16 35 45.7


line stmt bran cond sub pod time code
1             package JSON::RPC::Dispatcher::App;
2             $JSON::RPC::Dispatcher::App::VERSION = '0.0508';
3 1     1   1634 use Moose;
  1         474831  
  1         6  
4 1     1   7922 use JSON::RPC::Dispatcher;
  1         3  
  1         299  
5              
6             =head1 NAME
7              
8             JSON::RPC::Dispatcher::App - A base class for creating object oriented apps with JRD.
9              
10             =head1 VERSION
11              
12             version 0.0508
13              
14             =head1 SYNOPSIS
15              
16             Create your module:
17              
18             package MyApp;
19              
20             use Moose;
21             extends 'JSON::RPC::Dispatcher::App';
22              
23             sub sum {
24             my ($self, @params) = @_;
25             my $sum = 0;
26             $sum += $_ for @params;
27             return $sum;
28             }
29              
30             sub guess {
31             my ($self, $guess) = @_;
32             if ($guess == 10) {
33             return 'Correct!';
34             }
35             elsif ($guess > 10) {
36             confess [986, 'Too high.', $guess];
37             }
38             else {
39             confess [987, 'Too low.', $guess];
40             }
41             }
42              
43             __PACKAGE__->register_rpc_method_names( qw( sum guess ) );
44              
45             1;
46              
47             Then your plack F<app.psgi>:
48              
49             MyApp->new->to_app;
50              
51             =head1 DESCRIPTION
52              
53             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.
54              
55             =head1 METHODS
56              
57             The following methods are available from this class.
58              
59             =head2 new ( )
60              
61             A L<Moose> generated constructor.
62              
63             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:
64              
65             package MyApp;
66              
67             use Moose;
68             extends 'JSON::RPC::Dispatcher::App';
69              
70             has db => (
71             is => 'ro',
72             required => 1,
73             );
74              
75             sub make_it_go {
76             my ($self, @params) = @_;
77             my $sth = $self->db->prepare("select * from foo");
78             ...
79             }
80              
81             __PACKAGE__->register_rpc_method_names( qw(make_it_go) );
82              
83             1;
84              
85             In F<app.psgi>:
86              
87             my $db = DBI->connect(...);
88             MyApp->new(db=>$db)->to_app;
89              
90             =cut
91              
92             #--------------------------------------------------------
93              
94             =head2 register_rpc_method_names ( names )
95              
96             Class method. Registers a list of method names using L<JSON::RPC::Dispatcher>'s C<register> method.
97              
98             __PACKAGE__->register_rpc_method_names( qw( add subtract multiply divide ));
99              
100             =head3 names
101              
102             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:
103              
104             __PACKAGE__->register_rpc_method_names(
105             'add',
106             { name => 'ip_address', options => { with_plack_request => 1 } },
107             'concat',
108             );
109              
110             =cut
111              
112             sub _rpc_method_names {
113             return ();
114             }
115              
116             sub register_rpc_method_names {
117 1     1 1 651 my ($class, @methods) = @_;
118             $class->meta->add_around_method_modifier('_rpc_method_names', sub {
119 1     1   364 my ($orig, $self) = @_;
120 1         3 return ($orig->(), @methods);
121 1         6 });
122             }
123              
124             #--------------------------------------------------------
125              
126             =head2 to_app ( )
127              
128             Generates a PSGI/L<Plack> compatible app.
129              
130             =cut
131              
132             sub to_app {
133 0     0 1   my $self = shift;
134 0           my $rpc = JSON::RPC::Dispatcher->new;
135 0           my $ref;
136 0 0         if ($ref = $self->can('_rpc_method_names')) {
137 0           foreach my $method ($ref->()) {
138 0 0         if (ref $method eq 'HASH') {
139 0           my $name = $method->{name};
140 0     0     $rpc->register($name, sub { $self->$name(@_) }, $method->{options});
  0            
141             }
142             else {
143 0     0     $rpc->register($method, sub { $self->$method(@_) });
  0            
144             }
145             }
146             }
147 0           $rpc->to_app;
148             }
149              
150              
151             =head1 LEGAL
152              
153             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.
154              
155             =cut
156              
157             1;