jsonrpc-server 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +35 -0
- data/lib/json_server.rb +92 -52
- metadata +6 -5
data/README
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
== About
|
|
2
|
+
|
|
3
|
+
This is an implementation of {JSON RPC 2.0}[link:http://groups.google.com/group/json-rpc/web/json-rpc-2-0?pli=1] server
|
|
4
|
+
|
|
5
|
+
== Using
|
|
6
|
+
|
|
7
|
+
To make your rails controller JSON RPC 2.0 callable, make next include:
|
|
8
|
+
|
|
9
|
+
class TestController < ActionController::Base
|
|
10
|
+
include JSONServer
|
|
11
|
+
|
|
12
|
+
def summ(left, right)
|
|
13
|
+
return left+right
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
In your config/routing.rb you will have to add
|
|
18
|
+
|
|
19
|
+
post 'json' => 'test#index'
|
|
20
|
+
|
|
21
|
+
JSONServer will automaticaly check if posted json is valid JSON-RPC 2.0 request
|
|
22
|
+
and and fire called method. if method is not found - propper error will be sent.
|
|
23
|
+
|
|
24
|
+
Batch request are handled.
|
|
25
|
+
|
|
26
|
+
== Errors
|
|
27
|
+
|
|
28
|
+
You can raise standart errors, or JSONServer::Error with parameters :code,
|
|
29
|
+
:message, :data, which will be set for correspoding fields
|
|
30
|
+
:code defaults to -30000 if JSONServer::Error and to -32000 otherwise
|
|
31
|
+
:message defaults to "Runtime Error"
|
|
32
|
+
|
|
33
|
+
== TODO list
|
|
34
|
+
|
|
35
|
+
write tests
|
data/lib/json_server.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
1
3
|
module JSONServer
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
@@JSONRPCVersion = "2.0".freeze
|
|
6
|
+
|
|
7
|
+
class JSONRPCError < RuntimeError
|
|
4
8
|
attr_reader :code, :message, :data
|
|
5
9
|
def initialize obj = {}
|
|
6
10
|
@code = obj[:code] || -30000
|
|
@@ -9,87 +13,123 @@ module JSONServer
|
|
|
9
13
|
end
|
|
10
14
|
end
|
|
11
15
|
|
|
12
|
-
def
|
|
16
|
+
def dispatch_json_2 request
|
|
17
|
+
# here request specific errors are handled
|
|
13
18
|
begin
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
# no wraping, because single_request dispatcher does it
|
|
20
|
+
result = core_dispatch request
|
|
21
|
+
rescue JSONRPCError
|
|
22
|
+
result = wrap_error({ :code => $!.code,
|
|
23
|
+
:message => $!.message,
|
|
24
|
+
:data => $!.data
|
|
25
|
+
})
|
|
26
|
+
rescue RuntimeError
|
|
27
|
+
result = wrap_error({ :code => -32000,
|
|
28
|
+
:message => $!.message,
|
|
29
|
+
:data => $!.to_s
|
|
30
|
+
})
|
|
18
31
|
end
|
|
19
|
-
if
|
|
20
|
-
|
|
21
|
-
render :json => invalidRequest
|
|
22
|
-
return
|
|
23
|
-
end
|
|
24
|
-
res = data.collect { |single|
|
|
25
|
-
parseSingle single
|
|
26
|
-
}
|
|
27
|
-
render :json => res
|
|
28
|
-
return
|
|
32
|
+
if result != nil
|
|
33
|
+
return result.to_json
|
|
29
34
|
end
|
|
30
|
-
|
|
35
|
+
return ''
|
|
31
36
|
end
|
|
32
37
|
|
|
33
38
|
private
|
|
34
39
|
|
|
35
|
-
def
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
def core_dispatch request
|
|
41
|
+
begin
|
|
42
|
+
data = JSON.parse request
|
|
43
|
+
rescue JSON::ParserError
|
|
44
|
+
parse_error # converting error into json-rpc 2.0
|
|
45
|
+
end
|
|
46
|
+
if data.kind_of? Array
|
|
47
|
+
invalid_request if data.length == 0 # batch can not be empty
|
|
48
|
+
res = data.collect{ |single|
|
|
49
|
+
parse_single single
|
|
50
|
+
}
|
|
51
|
+
res.delete(nil)
|
|
52
|
+
return res unless res.length == 0
|
|
53
|
+
return nil
|
|
41
54
|
end
|
|
42
|
-
|
|
55
|
+
parse_single data
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def wrap data, id = nil
|
|
59
|
+
data.update({ :jsonrpc => @@JSONRPCVersion, :id => id })
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def wrap_error error, id = nil
|
|
63
|
+
wrap({ :error => error }, id)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def wrap_result result, id = nil
|
|
67
|
+
wrap({:result => result}, id)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def parse_single(data)
|
|
71
|
+
current_id = nil
|
|
43
72
|
begin
|
|
73
|
+
invalid_request unless data.kind_of?(Hash)
|
|
74
|
+
current_id = data["id"] unless data["id"] == nil
|
|
75
|
+
if data["jsonrpc"] != @@JSONRPCVersion ||
|
|
76
|
+
(not data["method"].kind_of?(String)) ||
|
|
77
|
+
data["method"] == ""
|
|
78
|
+
invalid_request
|
|
79
|
+
end
|
|
44
80
|
self.class.public_instance_methods.each { |method|
|
|
45
81
|
if method.to_s == data["method"]
|
|
46
|
-
if data["params"].
|
|
82
|
+
if data["params"].kind_of? Array
|
|
47
83
|
arr = data["params"]
|
|
48
84
|
elsif
|
|
49
85
|
arr = self.method(data["method"]).parameters.collect { |pd|
|
|
50
86
|
data["params"][pd[1].to_s]
|
|
51
87
|
}
|
|
52
88
|
end
|
|
53
|
-
result
|
|
54
|
-
|
|
89
|
+
result = self.send(data["method"], *arr)
|
|
90
|
+
if current_id != nil
|
|
91
|
+
return wrap_result(result, current_id)
|
|
92
|
+
else
|
|
93
|
+
return
|
|
94
|
+
end
|
|
55
95
|
end
|
|
56
96
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
result
|
|
60
|
-
|
|
61
|
-
|
|
97
|
+
method_not_found
|
|
98
|
+
rescue JSONRPCError
|
|
99
|
+
result = wrap_error({ :code => $!.code,
|
|
100
|
+
:message => $!.message,
|
|
101
|
+
:data => $!.data
|
|
102
|
+
}, current_id)
|
|
62
103
|
rescue RuntimeError
|
|
63
|
-
result
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
104
|
+
result = wrap_error({ :code => -32000,
|
|
105
|
+
:message => $!.message,
|
|
106
|
+
:data => $!.to_s
|
|
107
|
+
}, current_id)
|
|
67
108
|
end
|
|
68
|
-
return methodNotFound data["id"]
|
|
69
109
|
end
|
|
70
110
|
|
|
71
111
|
##
|
|
72
112
|
# Error handling section
|
|
73
113
|
##
|
|
74
114
|
|
|
75
|
-
def
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
115
|
+
def method_not_found
|
|
116
|
+
raise(JSONRPCError, {
|
|
117
|
+
:code => -32601,
|
|
118
|
+
:message => "Method not found."
|
|
119
|
+
}, caller)
|
|
80
120
|
end
|
|
81
121
|
|
|
82
|
-
def
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
122
|
+
def parse_error
|
|
123
|
+
raise(JSONRPCError, {
|
|
124
|
+
:code => -32700,
|
|
125
|
+
:message => "Parse error."
|
|
126
|
+
}, caller)
|
|
87
127
|
end
|
|
88
128
|
|
|
89
|
-
def
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
129
|
+
def invalid_request
|
|
130
|
+
raise(JSONRPCError, {
|
|
131
|
+
:code => -32600,
|
|
132
|
+
:message => "Invalid Request."
|
|
133
|
+
}, caller)
|
|
94
134
|
end
|
|
95
135
|
end
|
metadata
CHANGED
|
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
|
4
4
|
prerelease: false
|
|
5
5
|
segments:
|
|
6
6
|
- 0
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
version: 0.
|
|
7
|
+
- 2
|
|
8
|
+
- 0
|
|
9
|
+
version: 0.2.0
|
|
10
10
|
platform: ruby
|
|
11
11
|
authors:
|
|
12
12
|
- Dima Levchenko
|
|
@@ -14,7 +14,7 @@ autorequire:
|
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
16
|
|
|
17
|
-
date: 2011-05-
|
|
17
|
+
date: 2011-05-31 00:00:00 +03:00
|
|
18
18
|
default_executable:
|
|
19
19
|
dependencies: []
|
|
20
20
|
|
|
@@ -28,6 +28,7 @@ extra_rdoc_files: []
|
|
|
28
28
|
|
|
29
29
|
files:
|
|
30
30
|
- lib/json_server.rb
|
|
31
|
+
- README
|
|
31
32
|
has_rdoc: true
|
|
32
33
|
homepage: http://rubygems.org/gems/jsonrpc-server
|
|
33
34
|
licenses: []
|
|
@@ -55,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
55
56
|
version: "0"
|
|
56
57
|
requirements: []
|
|
57
58
|
|
|
58
|
-
rubyforge_project:
|
|
59
|
+
rubyforge_project: "[none]"
|
|
59
60
|
rubygems_version: 1.3.7
|
|
60
61
|
signing_key:
|
|
61
62
|
specification_version: 3
|