blix-rest 0.1.30

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c1b29a1f9ce5565c28991acebdb11f7a4e785db7760c59905936a9b2e8a6fa72
4
+ data.tar.gz: 5cc8fc070fb5fc09c3256dbc65b8087e6a17df7ed0bfc80b51fb9bd43ab38609
5
+ SHA512:
6
+ metadata.gz: bf6e866a78e15c268c364b4a87765a05440e1b6f1f6173f442d0a82045fbae4c94df7dcb2afb46c8e27f8ef017f0dea255de9cb85321059f2015f87fc3ee0404
7
+ data.tar.gz: 7e057e8b9b1dbc9bd1f46b952d071e51fc9d805b5e3236e8c5722902c839106bbece17de8175bcbf66a3ed2159c38121a88ad00d7ef68a94a70384e331e70176
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Clive Andrews
4
+
5
+
6
+ Permission is hereby granted, free of charge, to any person
7
+ obtaining a copy of this software and associated documentation
8
+ files (the "Software"), to deal in the Software without
9
+ restriction, including without limitation the rights to use,
10
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the
12
+ Software is furnished to do so, subject to the following
13
+ conditions:
14
+
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,457 @@
1
+ ## INSTALLATION
2
+
3
+ gem install blix-rest
4
+
5
+
6
+ ## CREATE A SIMPLE WEBSERVICE
7
+
8
+ #### put the following in config.ru
9
+
10
+
11
+ require 'blix/rest'
12
+
13
+ class HomeController < Blix::Rest::Controller
14
+
15
+ get '/hello', :accept=>[:html,:json], :default=>:html do
16
+ if format == :json
17
+ {"message"=>"hello world"}
18
+ else
19
+ "<h1>hello world</h1>"
20
+ end
21
+ end
22
+ end
23
+
24
+ run Blix::Rest::Server.new
25
+
26
+
27
+
28
+
29
+ #### at the command line ..
30
+
31
+ `ruby -S rackup -p3000`
32
+
33
+
34
+ #### now go to your browser and enter ..
35
+
36
+ `http://localhost:3000/hello`
37
+
38
+ or
39
+
40
+ `http://localhost:3000/hello.json`
41
+
42
+ ## Note on JSON
43
+
44
+ the default json parser uses multi json. load the specific json library you need
45
+ before loading `blix/rest`.
46
+
47
+ when using oj then you may need to set some default options eg:
48
+
49
+ `MultiJson.default_options = {:mode=>:custom, :use_as_json=>true}`
50
+
51
+ ## NOTE ON PATHS
52
+
53
+ `get '/user/:user_id/list`
54
+
55
+ `path_params[:user_id]` contains the content of the path at location :user_id
56
+
57
+ `get '/resource/*wildpath'`
58
+
59
+ `path_params[:wildpath]` contains the remainder of the path where the * is.
60
+
61
+ if there is a more specific path then it will be used first :
62
+
63
+ `get '/resource/aaa'` will be used before `get '/resource/*'`
64
+
65
+ `get '/*'` will be used as a default path if no other paths match.
66
+
67
+ `all '/mypath'` will accept all http_methods but if a more specific handler
68
+ is specified then it will be used first.
69
+
70
+
71
+ ### Path options
72
+
73
+ :accept : the format or formats to accept eg: :html or [:png, :jpeg]
74
+ :default : default format if not derived through oher means.
75
+ :force : force response into the given format
76
+ :query : derive format from request query (default: false)
77
+ :extension : derive format from path extension (default: true)
78
+
79
+
80
+ use `:accept=>:*` in combination with `:force` to accept all request formats.
81
+
82
+ ## APPLICATION MOUNT POINT
83
+
84
+ this is the path of the mount path of the application
85
+
86
+ this will be set to the environment variable `BLIX_REST_ROOT` if present
87
+
88
+ otherwise set it manually with:
89
+
90
+ `Blix::Rest.set_path_root( "/myapplication")`
91
+
92
+
93
+
94
+
95
+ ## GENERATE AN ERROR RESPONSE
96
+
97
+ `send_error(message,status,headers)`
98
+
99
+ or for standard headers and status 406 just ..
100
+
101
+ `send_error "my error message`
102
+
103
+
104
+
105
+ ## HEADERS && STATUS
106
+
107
+ add special headers to your response with eg:
108
+
109
+ `add_headers( "AAA"=>"xxx","BBB"=>"yyyy")`
110
+
111
+ change the status of a success response with eg:
112
+
113
+ `set_status(401)`
114
+
115
+
116
+ to specify __ALL__ the headers for a given format of response use eg:
117
+
118
+ srv = Blix::Rest::Server.new
119
+ srv.set_custom_headers(:html, 'Content-Type'=>'text/html; charset=utf-8', 'X-OTHER'=>'')
120
+
121
+ ...
122
+ srv.run
123
+
124
+ remember to always set at least the content type!
125
+
126
+ ## BASIC AUTH
127
+
128
+ in controller..
129
+
130
+ login,password = get_basic_auth
131
+ auth_error( "invalid login or password" ) unless .... # validate login and password
132
+
133
+
134
+
135
+
136
+ ## REQUEST FORMAT
137
+
138
+ you can provide custom responses to a request format by registering a format parser
139
+ for that format. you can also override the standard html,json or xml behavior.
140
+
141
+ Note that the format for a non standard (html/json/xml) request is only taken from
142
+ the extension part ( after the .) of the url ... eg
143
+
144
+ `http://mydomain.com/mypage.jsonp` will give a format of jsonp
145
+
146
+ you can specify the :default option in your route for a fallback format other than :json
147
+ eg `:default=>:html`
148
+
149
+
150
+ class MyParser < FormatParser
151
+
152
+ def set_default_headers(headers)
153
+ headers[CACHE_CONTROL]= CACHE_NO_STORE
154
+ headers[PRAGMA] = NO_CACHE
155
+ headers[CONTENT_TYPE] = CONTENT_TYPE_JSONP
156
+ end
157
+
158
+ def format_error(message)
159
+ message.to_s
160
+ end
161
+
162
+ def format_response(value,response)
163
+ response.content = "<script>load(" +
164
+ MultiJson.dump( value) +
165
+ ")</script>"
166
+ end
167
+ end
168
+
169
+
170
+ s = Blix::Rest::Server.new
171
+ s.register_parser(:jsonp,MyParser.new)
172
+
173
+
174
+ Then in your controller accept that format..
175
+
176
+
177
+ get "/details" :accept=>[:jsonp] do
178
+ {"id"=>12}
179
+ end
180
+
181
+ ## CUSTOM RESPONSE WITHOUT CUSTOM PARSER
182
+
183
+ to force a response in a certain format use the :force option in your route.
184
+
185
+ to return a custom response use `:force=>:raw` . You will have to specify all the
186
+ headers and the body is returned as it is.
187
+
188
+ use the following to accept requests in a special format ..
189
+
190
+ get '/custom', :accept=>:xyz, :force=>:raw do
191
+ add_headers 'Content-Type'=>'text/xyz'
192
+
193
+ "xyz"
194
+ end
195
+
196
+ ## FORMATS
197
+
198
+ the format of a request is derived from
199
+
200
+ 1. the `:force` option value if present
201
+
202
+ 2. the request query `format` parameter if the `:query` option is true
203
+
204
+ 3. the url extension unless the `:extension` option is false.
205
+
206
+ 4. the accept header format
207
+
208
+ 5. the format specified in the `:default` option
209
+
210
+ 6. `:json`
211
+
212
+
213
+ ## Controller
214
+
215
+ Blix::Rest::Controller
216
+
217
+ base class for controllers. within your block handling a particular route you
218
+ have access to a number of methods
219
+
220
+
221
+ env : the request environment hash
222
+ method : the request method lowercase( 'get'/'post' ..)
223
+ req : the rack request
224
+ body : the request body as a string
225
+ query_params : a hash of parameters as passed in the url as parameters
226
+ path_params : a hash of parameters constructed from variable parts of the path
227
+ post_params : a hash of parameters passed in the body of the request
228
+ params : all the params combined
229
+ user : the user making this request ( or nil if
230
+ format : the format the response should be in :json or :html
231
+ before : before hook ( opts ) - remember to add 'super' as first line !!!
232
+ after : after hook (opts,response)- remember to add 'super' as first line !!!
233
+ proxy : forward the call to another service (service,path, opts={}) , :include_query=>true/false
234
+ session : req.session
235
+ redirect : (path, status=302) redirect to another url.
236
+ request_ip : the ip of the request
237
+ render_erb : (template_name [,:layout=>name])
238
+ path_for : (path) give the correct path for an internal path
239
+ url_for : (path) give the full url for an internal path
240
+ h : escape html string to avoid XSS
241
+ escape_javascript : escape a javascript string
242
+ server_options : options as passed to server at create time
243
+ mode_test? : test mode ?
244
+ mode_production? : production mode ?
245
+ mode_development? : development mode?
246
+
247
+
248
+ get_session_id(session_name, opts={}) :
249
+ refresh_session_id(session_name, opts={}) :
250
+
251
+ to accept requests other than json then set `:accept=>[:json,:html]` as options in the route
252
+
253
+ eg `post '/myform' :accept=>[:html] # this will only accept html requests.`
254
+
255
+ ### Sessions
256
+
257
+ the following methods are available in the controller for managing sessions.
258
+
259
+ get_session_id(session_name, opts={})
260
+
261
+ this will set up a session and setup the relevant cookie headers forthe browser.
262
+
263
+ refresh_session_id(session_name, opts={})
264
+
265
+ this will generate a new session_id and setup the relevant headers
266
+
267
+ options can include:
268
+
269
+ :secure => true # secure cookies only
270
+ :http = >true # cookies for http only not javascript requests
271
+ :samesite =>:strict # use strict x-site policy
272
+ :samesite =>:lax # use lax x-site policy
273
+
274
+
275
+
276
+
277
+ ## Views
278
+
279
+ the location of your views defaults to `app/views` otherwise set it manually with:
280
+
281
+ globally eg:
282
+
283
+ Blix::Rest.set_erb_root ::File.expand_path('../lib/myapp/views', __FILE__)
284
+
285
+ or per controller eg:
286
+
287
+ class MyController < Blix::Rest::Controller
288
+
289
+ erb_dir ::File.expand_path('../..', __FILE__)
290
+
291
+ end
292
+
293
+ then within a controller render your view with.
294
+
295
+ render_erb( "users/index", :layout=>'layouts/main', :locals=>{:name=>"charles"})
296
+
297
+ ( locals work from ruby 2.1 )
298
+
299
+
300
+ #### directory structure
301
+
302
+ views
303
+ -----
304
+ users
305
+ -----
306
+ index.html.erb
307
+ layouts
308
+ -------
309
+ main.html.erb
310
+
311
+
312
+ ## Logging
313
+
314
+ Blix::Rest.logger = Logger.new('/var/log/myapp.log')
315
+
316
+
317
+ ## Testing a Service with cucumber
318
+
319
+
320
+ in features/support/setup.rb
321
+
322
+ require 'blix/rest/cucumber'
323
+
324
+ and setup your database connections etc
325
+
326
+
327
+ in features/support/hooks.rb
328
+
329
+ reset your database
330
+
331
+
332
+
333
+ now you can use the following in scenarios ........
334
+
335
+ Given user guest gets "/info"
336
+
337
+ Given the following users exist:
338
+ | name | level |
339
+ | anon | guest |
340
+ | bob | user |
341
+ | mary | provider |
342
+ | paul | user |
343
+ | admin | admin |
344
+
345
+ Given user mary posts "/worlds" with {"name":"narnia"} [..or gets/puts/deletes]
346
+ Then store the "id" as "world_id"
347
+
348
+ Given user bob posts "/worlds/:world_id" with {"the_world_id"::world_id }
349
+
350
+ Then the status should be 200
351
+ Then the data type should be "r_type"
352
+ Then the data length should be 3
353
+ Then there should be an error
354
+ Then the error message should include "unique"
355
+ Then the data "name" should == "bob"
356
+ Then the data should include "name"
357
+
358
+ And explain
359
+
360
+
361
+ NOTE : if you need to set up your database with users then you can use the following hook ..
362
+
363
+ in features/support/world.rb .........
364
+
365
+ class RestWorld
366
+
367
+ # add a hook to create the user in the database -
368
+ #
369
+ def before_user_create(user,hash)
370
+ name = hash["name"]
371
+ u = MyUser.new
372
+ u.set(:user_wid, name)
373
+ u.set(:name,name)
374
+ u.set(:is_super,true) if hash["level"] == "super"
375
+ u.save
376
+ store["myuser_#{name}_id"] = u.id.to_s
377
+ end
378
+ end
379
+
380
+ now you can also use eg `:myuser_foo_id` within a request path/json.
381
+
382
+
383
+
384
+ ## Manage Assets
385
+
386
+
387
+ require 'blix/assets'
388
+
389
+
390
+ The asset manager stores a hash of the asset data and the current unique file suffix for each asset in its own file.
391
+ This config file is stored in a config directory. The default is 'config/assets' but another location can be specified.
392
+
393
+
394
+ Blix::AssetManager.config_dir = "myassets/config/location" # defaults to `"config/assets"`
395
+
396
+
397
+ ### Compile your assets
398
+
399
+ require 'blix/assets'
400
+
401
+ ......
402
+ ......
403
+ ASSETS = ['admin.js', 'admin.css', 'standard.js']
404
+ ASSETS.each do |name|
405
+
406
+ compiled_asset = environment[name].to_s
407
+
408
+ Blix::AssetManager.if_modified(name,compiled_asset,:rewrite=>true) do |a|
409
+
410
+ filename = File.join(ROOT,"public","assets",a.newname)
411
+ puts "writing #{name} to #{filename}"
412
+ File.write filename,compiled_asset
413
+
414
+ File.unlink File.join(ROOT,"public","assets",a.oldname) if a.oldname
415
+ end
416
+
417
+ end
418
+
419
+
420
+ ### In your erb view
421
+
422
+
423
+ eg:
424
+
425
+ require 'blix/assets'
426
+
427
+ ........
428
+
429
+ <script src="<%= asset_path('assets/standard.js') %>" type="text/javascript"></script>
430
+
431
+ or
432
+
433
+ <%= asset_tag('/assets/standard.js') %>
434
+
435
+
436
+ ### or in your controller
437
+
438
+ eg:
439
+
440
+ require 'blix/assets'
441
+
442
+ ........
443
+
444
+ path = asset_path('assets/standard.js')
445
+
446
+
447
+
448
+ #### NOTE ON ASSETS!!
449
+
450
+ In production mode the compiled version of the assets will be used which will have a unique file name.
451
+
452
+ In production the expiry date of your assets can be set to far in the future to take advantage of cacheing.
453
+
454
+ In development or test mode the standard name will be used which then will make use of your asset pipeline ( eg sprockets )
455
+
456
+ Asset names can contain only one extension. if there are more extensions eg: 'myfile.extra.css' then only the last
457
+ extension will be used: in this case the name will be simplified to 'myfile.css' !!!