webservice 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/lib/webservice.rb +1 -0
- data/lib/webservice/base.rb +167 -16
- data/lib/webservice/version.rb +2 -2
- data/test/service/app.rb +8 -0
- data/test/test_app.rb +30 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b43248423b9aeba87a88f63b6a708167bbf7d723
|
4
|
+
data.tar.gz: 35b9cd86f34c708a4d55f7f61a08a878f4e19d12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: def6d86899d29ca10acb0c70af15de8887005fc47dc9f1d5586103eb98033d7e68d5c44744c51b30493cbcef344a565f9dbcc21c6681aa55257e42c772c0f307
|
7
|
+
data.tar.gz: 2417ece5303df96025515574a343e2b21eaa1e08015ff7cfe11822a9d9d757c918a798e149d1d03f24b74a7574e0ef6e4625778b6b63b6b42fa0f403c31adb19
|
data/lib/webservice.rb
CHANGED
data/lib/webservice/base.rb
CHANGED
@@ -3,21 +3,85 @@
|
|
3
3
|
|
4
4
|
module Webservice
|
5
5
|
|
6
|
-
class Base
|
7
6
|
|
8
|
-
|
7
|
+
module Helpers
|
8
|
+
## add some more helpers
|
9
|
+
## "inspired" by sinatra (mostly) - for staying compatible
|
10
|
+
## see https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb
|
11
|
+
|
12
|
+
## todo -- add redirect/redirect_to
|
13
|
+
## add status -- why? why not??
|
14
|
+
|
15
|
+
# Halt processing and return the error status provided.
|
16
|
+
def error(code, body=nil)
|
17
|
+
code = 500
|
18
|
+
body = code.to_str if code.respond_to? :to_str
|
19
|
+
|
20
|
+
response.body = body unless body.nil?
|
21
|
+
halt code
|
22
|
+
end
|
23
|
+
|
24
|
+
# Halt processing and return a 404 Not Found.
|
25
|
+
def not_found(body=nil)
|
26
|
+
error 404, body
|
27
|
+
end
|
28
|
+
|
29
|
+
# Set multiple response headers with Hash.
|
30
|
+
def headers(hash=nil)
|
31
|
+
response.headers.merge! hash if hash
|
32
|
+
response.headers
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
## (simple) content_type helper - all "hard-coded" for now; always uses utf-8 too
|
38
|
+
def content_type( type=nil )
|
39
|
+
return response['Content-Type'] unless type
|
40
|
+
|
41
|
+
if type.to_sym == :json
|
42
|
+
response['Content-Type'] = 'application/json; charset=utf-8'
|
43
|
+
elsif type.to_sym == :js || type.to_sym == :javascript
|
44
|
+
response['Content-Type'] = 'application/javascript; charset=utf-8'
|
45
|
+
## use 'text/javascript; charset=utf-8' -- why? why not??
|
46
|
+
## note: ietf recommends application/javascript
|
47
|
+
elsif type.to_sym == :csv || type.to_sym == :text || type.to_sym == :txt
|
48
|
+
response['Content-Type'] = 'text/plain; charset=utf-8'
|
49
|
+
elsif type.to_sym == :html || type.to_sym == :htm
|
50
|
+
response['Content-Type'] = 'text/html; charset=utf-8'
|
51
|
+
else
|
52
|
+
### unknown type; do nothing - sorry; issue warning - why? why not??
|
53
|
+
end
|
54
|
+
end ## method content_type
|
55
|
+
end ## module Helpers
|
9
56
|
|
10
57
|
|
58
|
+
class Base
|
59
|
+
include Helpers
|
60
|
+
|
11
61
|
class << self
|
12
62
|
|
13
63
|
## todo/check: all verbs needed! (supported) - why, why not??
|
14
|
-
|
15
|
-
define_method( method.downcase ) do |pattern, &block|
|
16
|
-
puts "[debug] Webservice::Base.#{method.downcase} - add route #{method} '#{pattern}' to #<#{self.name}:#{self.object_id}> : #{self.class.name}"
|
64
|
+
## e.g. add LINK, UNLINK ??
|
17
65
|
|
18
|
-
|
19
|
-
|
20
|
-
|
66
|
+
# Note: for now defining a `GET` handler also automatically defines
|
67
|
+
# a `HEAD` handler (follows sinatra convention)
|
68
|
+
def get( pattern, &block)
|
69
|
+
route( 'GET', pattern, &block )
|
70
|
+
route( 'HEAD', pattern, &block )
|
71
|
+
end
|
72
|
+
|
73
|
+
def post( pattern, &block) route( 'POST', pattern, &block ); end
|
74
|
+
def patch( pattern, &block) route( 'PATCH', pattern, &block ); end
|
75
|
+
def put( pattern, &block) route( 'PUT', pattern, &block ); end
|
76
|
+
def delete( pattern, &block) route( 'DELETE', pattern, &block ); end
|
77
|
+
def head( pattern, &block) route( 'HEAD', pattern, &block ); end
|
78
|
+
def options( pattern, &block) route( 'OPTIONS', pattern, &block ); end
|
79
|
+
|
80
|
+
def route( method, pattern, &block )
|
81
|
+
puts "[debug] Webservice::Base.#{method.downcase} - add route #{method} '#{pattern}' to #<#{self.name}:#{self.object_id}> : #{self.class.name}"
|
82
|
+
|
83
|
+
## note: for now use the sintatra-style patterns (with mustermann)
|
84
|
+
routes[method] << [Mustermann::Sinatra.new(pattern), block]
|
21
85
|
end
|
22
86
|
|
23
87
|
|
@@ -26,6 +90,17 @@ class Base
|
|
26
90
|
end
|
27
91
|
|
28
92
|
|
93
|
+
def environment
|
94
|
+
## include APP_ENV why? why not?
|
95
|
+
## todo -- cache value? why why not? (see/follow sinatara set machinery ??)
|
96
|
+
(ENV['RACK_ENV'] || :development).to_sym
|
97
|
+
end
|
98
|
+
|
99
|
+
def development?() environment == :development; end
|
100
|
+
def production?() environment == :production; end
|
101
|
+
def test?() environment == :test; end
|
102
|
+
|
103
|
+
|
29
104
|
## convenience method
|
30
105
|
def run!
|
31
106
|
puts "[debug] Webservice::Base.run! - self = #<#{self.name}:#{self.object_id}> : #{self.class.name}" # note: assumes self is class
|
@@ -39,7 +114,6 @@ class Base
|
|
39
114
|
end ## class << self
|
40
115
|
|
41
116
|
|
42
|
-
|
43
117
|
attr_reader :request
|
44
118
|
attr_reader :response
|
45
119
|
attr_reader :params
|
@@ -67,7 +141,6 @@ class Base
|
|
67
141
|
throw :halt, response
|
68
142
|
end
|
69
143
|
|
70
|
-
|
71
144
|
private
|
72
145
|
|
73
146
|
def route_eval
|
@@ -78,6 +151,7 @@ private
|
|
78
151
|
if url_params ## note: params returns nil if no match
|
79
152
|
## puts " BINGO! url_params: #{url_params.inspect}"
|
80
153
|
if !url_params.empty? ## url_params hash NOT empty (e.g. {}) merge with req params
|
154
|
+
## todo/fix: check merge order - params overwrites url_params - why? why not??
|
81
155
|
@params = url_params.merge( params )
|
82
156
|
end
|
83
157
|
handle_response( instance_eval( &block ))
|
@@ -89,20 +163,97 @@ private
|
|
89
163
|
end
|
90
164
|
|
91
165
|
|
166
|
+
|
167
|
+
|
92
168
|
def handle_response( obj )
|
93
|
-
puts "[Webservice::Base#handle_response] - obj : #{obj.class.name}"
|
169
|
+
puts "[Webservice::Base#handle_response (#{request.path_info}) params: #{params.inspect}] - obj : #{obj.class.name}"
|
170
|
+
pp obj
|
94
171
|
|
95
|
-
|
172
|
+
## "magic" param format; default to json
|
173
|
+
format = params['format'] || 'json'
|
96
174
|
|
97
|
-
if
|
98
|
-
|
175
|
+
if format == 'csv' || format == 'txt'
|
176
|
+
text = generate_csv( obj )
|
177
|
+
content_type :text
|
178
|
+
response.write text
|
179
|
+
elsif format == 'html' || format == 'htm'
|
180
|
+
text = generate_html_table( obj )
|
181
|
+
content_type :html
|
182
|
+
response.write text
|
99
183
|
else
|
100
|
-
|
101
|
-
|
184
|
+
json = generate_json( obj )
|
185
|
+
|
186
|
+
callback = params.delete('callback')
|
187
|
+
|
188
|
+
if callback
|
189
|
+
content_type :js
|
190
|
+
response.write "#{callback}(#{json})"
|
191
|
+
else
|
192
|
+
content_type :json
|
193
|
+
response.write json
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end # method handle_response
|
197
|
+
|
198
|
+
|
199
|
+
def generate_csv( recs )
|
200
|
+
## note: for now assumes (only works with) array of hash records e.g.:
|
201
|
+
## [
|
202
|
+
## { key: 'at', name: 'Austria', ...},
|
203
|
+
## { key: 'mx', name: 'Mexico', ...},
|
204
|
+
## ...
|
205
|
+
## ]
|
206
|
+
|
207
|
+
## :col_sep => "\t"
|
208
|
+
## :col_sep => ";"
|
209
|
+
|
210
|
+
## todo: use rec.key for headers/first row
|
211
|
+
|
212
|
+
## pp recs
|
213
|
+
|
214
|
+
CSV.generate do |csv|
|
215
|
+
recs.each do |rec|
|
216
|
+
csv << rec.values
|
217
|
+
end
|
102
218
|
end
|
103
219
|
end
|
104
220
|
|
105
221
|
|
222
|
+
def generate_html_table( recs )
|
223
|
+
## note: for now assumes (only works with) array of hash records e.g.:
|
224
|
+
## [
|
225
|
+
## { key: 'at', name: 'Austria', ...},
|
226
|
+
## { key: 'mx', name: 'Mexico', ...},
|
227
|
+
## ...
|
228
|
+
## ]
|
229
|
+
|
230
|
+
## pp recs
|
231
|
+
|
232
|
+
buf = ""
|
233
|
+
buf << "<table>\n"
|
234
|
+
recs.each do |rec|
|
235
|
+
buf << " <tr>"
|
236
|
+
rec.values.each do |value|
|
237
|
+
buf << "<td>#{value}</td>"
|
238
|
+
end
|
239
|
+
buf << "</tr>\n"
|
240
|
+
end
|
241
|
+
buf << "</table>\n"
|
242
|
+
buf
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
def generate_json( obj )
|
247
|
+
if obj.respond_to? :as_json_v2 ## try (our own) serializer first
|
248
|
+
obj.as_json_v2
|
249
|
+
elsif obj.respond_to? :as_json ## try (activerecord) serializer
|
250
|
+
obj.as_json_v2
|
251
|
+
else
|
252
|
+
## just try/use to_json
|
253
|
+
obj.to_json
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
106
257
|
end # class Base
|
107
258
|
|
108
259
|
end # module Webservice
|
data/lib/webservice/version.rb
CHANGED
data/test/service/app.rb
CHANGED
@@ -22,6 +22,14 @@ get '/halt_error' do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
|
25
|
+
get '/countries(.:format)?' do
|
26
|
+
## array of hash records
|
27
|
+
[ { key: 'at', name: 'Austria' },
|
28
|
+
{ key: 'mx', name: 'Mexico' } ]
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
25
33
|
get '/:message/:name' do
|
26
34
|
message = params['message']
|
27
35
|
name = params['name']
|
data/test/test_app.rb
CHANGED
@@ -57,9 +57,9 @@ class TestApp < MiniTest::Test
|
|
57
57
|
assert last_response.ok?
|
58
58
|
assert_equal %q{"key format"}, last_response.body
|
59
59
|
|
60
|
-
get '/ottakringer.
|
60
|
+
get '/ottakringer.xxx'
|
61
61
|
assert last_response.ok?
|
62
|
-
assert_equal %q{"ottakringer
|
62
|
+
assert_equal %q{"ottakringer xxx"}, last_response.body
|
63
63
|
|
64
64
|
get '/ottakringer'
|
65
65
|
assert last_response.ok?
|
@@ -67,6 +67,34 @@ class TestApp < MiniTest::Test
|
|
67
67
|
end
|
68
68
|
|
69
69
|
|
70
|
+
def test_countries
|
71
|
+
|
72
|
+
get '/countries.csv'
|
73
|
+
assert last_response.ok?
|
74
|
+
assert_equal <<CSV, last_response.body
|
75
|
+
at,Austria
|
76
|
+
mx,Mexico
|
77
|
+
CSV
|
78
|
+
|
79
|
+
get '/countries.html'
|
80
|
+
assert last_response.ok?
|
81
|
+
assert_equal <<HTML, last_response.body
|
82
|
+
<table>
|
83
|
+
<tr><td>at</td><td>Austria</td></tr>
|
84
|
+
<tr><td>mx</td><td>Mexico</td></tr>
|
85
|
+
</table>
|
86
|
+
HTML
|
87
|
+
|
88
|
+
get '/countries.json'
|
89
|
+
assert last_response.ok?
|
90
|
+
assert_equal %q<[{"key":"at","name":"Austria"},{"key":"mx","name":"Mexico"}]>, last_response.body
|
91
|
+
|
92
|
+
get '/countries'
|
93
|
+
assert last_response.ok?
|
94
|
+
assert_equal %q<[{"key":"at","name":"Austria"},{"key":"mx","name":"Mexico"}]>, last_response.body
|
95
|
+
end # method test_countries
|
96
|
+
|
97
|
+
|
70
98
|
def test_halt
|
71
99
|
## get '/halt/404'
|
72
100
|
get '/halt/404'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webservice
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logutils
|