1JSON::RPC(3) User Contributed Perl Documentation JSON::RPC(3)
2
3
4
6 JSON::RPC - JSON RPC 2.0 Server Implementation
7
9 # app.psgi
10 use strict;
11 use JSON::RPC::Dispatch;
12
13 my $dispatch = JSON::RPC::Dispatch->new(
14 prefix => "MyApp::JSONRPC::Handler",
15 router => Router::Simple->new( ... )
16 );
17
18 sub {
19 my $env = shift;
20 $dispatch->handle_psgi($env);
21 };
22
24 JSON::RPC is a set of modules that implement JSON RPC 2.0 protocol.
25
26 If you are using old JSON::RPC code (up to 0.96), DO NOT EXPECT
27 YOUR CODE TO WORK WITH THIS VERSION. THIS VERSION IS
28 ****BACKWARDS INCOMPATIBLE****
29
31 The JSON::RPC::Dispatch object is responsible for marshalling the
32 request.
33
34 my $dispatch = JSON::RPC::Dispatch->new(
35 router => ...,
36 );
37
38 The routing between the JSON RPC methods and their implementors are
39 handled by Router::Simple. For example, if you want to map method "foo"
40 to a "MyApp::JSONRPC::Handler" object instance's "handle_foo" method,
41 you specify something like the following in your router instance:
42
43 use Router::Simple::Declare;
44 my $router = router {
45 connect "foo" => {
46 handler => "+MyApp::JSONRPC::Handler",
47 action => "handle_foo"
48 };
49 };
50
51 my $dispatch = JSON::RPC::Dispatch->new(
52 router => $router,
53 );
54
55 The "+" prefix in the handler classname denotes that it is already a
56 fully qualified classname. Without the prefix, the value of "prefix" in
57 the dispatch object will be used to qualify the classname. If you
58 specify it in your Dispatch instance, you may omit the prefix part to
59 save you some typing:
60
61 use JSON::RPC::Dispatch;
62 use Router::Simple::Declare;
63
64 my $router = router {
65 connect "foo" => {
66 handler => "Foo",
67 action => "process",
68 };
69 connect "bar" => {
70 handler => "Bar",
71 action => "process"
72 }
73 };
74 my $dispatch = JSON::RPC::Dispatch->new(
75 prefix => "MyApp::JSONRPC::Handler",
76 router => $router,
77 );
78
79 # The above will roughly translate to the following:
80 #
81 # for method "foo"
82 # my $handler = MyApp::JSONRPC::Handler::Foo->new;
83 # $handler->process( ... );
84 #
85 # for method "bar"
86 # my $handler = MyApp::JSONRPC::Handler::Bar->new;
87 # $handler->process( ... );
88
89 The implementors are called handlers. Handlers are simple objects, and
90 will be instantiated automatically for you. Their return values are
91 converted to JSON objects automatically.
92
93 You may also choose to pass objects in the handler argument to connect
94 in your router. This will save you the cost of instantiating the
95 handler object, and you also don't have to rely on us instantiating
96 your handler object.
97
98 use Router::Simple::Declare;
99 use MyApp::JSONRPC::Handler;
100
101 my $handler = MyApp::JSONRPC::Handler->new;
102 my $router = router {
103 connect "foo" => {
104 handler => $handler,
105 action => "handle_foo"
106 };
107 };
108
110 Your handlers are objects responsible for returning some sort of
111 reference structure that can be properly encoded via JSON/JSON::XS. The
112 handler only needs to implement the methods that you specified in your
113 router.
114
115 The handler methods will receive the following parameters:
116
117 sub your_handler_method {
118 my ($self, $params, $procedure, @extra_args) = @_;
119
120 return $some_structure;
121 }
122
123 In most cases you will only need the parameters. The exact format of
124 the $params is dependent on the caller -- you will be passed whatever
125 JSON structure that caller used to call your handler.
126
127 $procedure is an instance of JSON::RPC::Procedure. Use it if you need
128 to figure out more about the procedure.
129
130 @extra_args is optional, and will be filled with whatever extra
131 arguments you passed to handle_psgi(). For example,
132
133 # app.psgi
134 sub {
135 $dispatch->handle_psgi($env, "arg1", "arg2", "arg3");
136 }
137
138 will cause your handlers to receive the following arguments:
139
140 sub your_handler_method {
141 my ($self, $params, $procedure, $arg1, $arg2, $arg3) = @_;
142
143 }
144
145 This is convenient if you have application-specific data that needs to
146 be passed to your handlers.
147
149 If you already have a web app (and whatever framework you might already
150 have), you may choose to embed JSON::RPC in your webapp instead of
151 directly calling it in your PSGI application.
152
153 For example, if you would like to your webapp's "rpc" handler to
154 marshall the JSON RPC request, you can do something like the following:
155
156 package MyApp;
157 use My::Favorite::WebApp;
158
159 sub rpc {
160 my ($self, $context) = @_;
161
162 my $dispatch = ...; # grab it from somewhere
163 $dispatch->handle_psgi( $context->env );
164 }
165
167 When your handler dies, it is automatically included in the response
168 hash, unless no response was requested (see "NOTIFICATIONS").
169
170 For example, something like below
171
172 sub rpc {
173 ...
174 if ($bad_thing_happend) {
175 die "Argh! I failed!";
176 }
177 }
178
179 Would result in a response like
180
181 {
182 error => {
183 code => -32603,
184 message => "Argh! I failed! at ...",
185 }
186 }
187
188 However, you can include custom data by die()'ing with a hash:
189
190 sub rpc {
191 ...
192 if ($bad_thing_happend) {
193 die { message => "Argh! I failed!", data => time() };
194 }
195 }
196
197 This would result in:
198
199 {
200 error => {
201 code => -32603,
202 message => "Argh! I failed! at ...",
203 data => 1339817722,
204 }
205 }
206
208 Notifications are defined as procedures without an id. Notification
209 handling does not produce a response. When all procedures are
210 notifications no content is returned (if the request is valid). To
211 maintain some basic compatibility with relaxed client implementations,
212 JSON::RPC::Dispatch includes responses when procedures do not have a
213 "jsonrpc" field set to "2.0".
214
215 Note that no error is returned in response to a notification when the
216 handler dies or when the requested method is not available.
217
218 For example, a request structure like this:
219
220 [
221 {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
222 {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
223 {"jsonrpc": "2.0", "method": "keep_alive"},
224 {"jsonrpc": "2.0", "method": "get_data", "id": "9"}
225 ]
226
227 Would result in a response like
228
229 [
230 {"jsonrpc": "2.0", "result": 7, "id": "1"},
231 {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}
232 ]
233
235 Eh, not compatible at all. JSON RPC 0.xx was fine, but it predates
236 PSGI, and things are just... different before and after PSGI.
237
238 Code at version 0.96 has been moved to JSON::RPC::Legacy namespace, so
239 change your application to use JSON::RPC::Legacy if you were using the
240 old version.
241
243 Daisuke Maki
244
245 Shinichiro Aska
246
247 Yoshimitsu Torii
248
250 Makamaka Hannyaharamitu, <makamaka[at]cpan.org> - JSON::RPC modules up
251 to 0.96
252
254 The JSON::RPC module is
255
256 Copyright (C) 2011 by Daisuke Maki
257
258 This library is free software; you can redistribute it and/or modify it
259 under the same terms as Perl itself, either Perl version 5.8.0 or, at
260 your option, any later version of Perl 5 you may have available.
261
262 See JSON::RPC::Legacy for copyrights and license for previous versions.
263
264
265
266perl v5.28.0 2018-07-14 JSON::RPC(3)