lotus-controller 0.1.0 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +127 -0
- data/{LICENSE.txt → LICENSE.md} +0 -0
- data/README.md +259 -15
- data/lib/lotus/action.rb +20 -0
- data/lib/lotus/action/callbacks.rb +20 -2
- data/lib/lotus/action/configurable.rb +48 -0
- data/lib/lotus/action/cookie_jar.rb +29 -5
- data/lib/lotus/action/exposable.rb +12 -5
- data/lib/lotus/action/mime.rb +215 -32
- data/lib/lotus/action/params.rb +21 -4
- data/lib/lotus/action/rack.rb +81 -0
- data/lib/lotus/action/redirect.rb +6 -1
- data/lib/lotus/action/session.rb +1 -0
- data/lib/lotus/action/throwable.rb +37 -36
- data/lib/lotus/controller.rb +216 -17
- data/lib/lotus/controller/configuration.rb +510 -0
- data/lib/lotus/controller/dsl.rb +6 -4
- data/lib/lotus/controller/version.rb +1 -1
- data/lib/lotus/http/status.rb +5 -62
- data/lib/rack-patch.rb +4 -2
- data/lotus-controller.gemspec +3 -3
- metadata +26 -56
- data/.gitignore +0 -10
- data/.travis.yml +0 -5
- data/.yardopts +0 -4
- data/Gemfile +0 -15
- data/Rakefile +0 -17
- data/test/action/callbacks_test.rb +0 -99
- data/test/action/params_test.rb +0 -29
- data/test/action_test.rb +0 -31
- data/test/controller_test.rb +0 -24
- data/test/cookies_test.rb +0 -36
- data/test/fixtures.rb +0 -501
- data/test/integration/mime_type_test.rb +0 -175
- data/test/integration/routing_test.rb +0 -141
- data/test/integration/sessions_test.rb +0 -63
- data/test/redirect_test.rb +0 -20
- data/test/session_test.rb +0 -19
- data/test/test_helper.rb +0 -24
- data/test/throw_test.rb +0 -93
- data/test/version_test.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 596855476b8c72b53e86d1101e54edb8137e4206
|
4
|
+
data.tar.gz: 40df1097012f2d091aad3eff3734cdd71077ecde
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebeec9005fb1c28cc195af167872a9d6aa206c65c951488b9671c11a472ff36c017c3c647c9e964db92a903cfa16b7a0f6b3b4dab777d1c18fa7de7438c590e5
|
7
|
+
data.tar.gz: 2626b3767d3a68ef4a2b7418c3d0711e68e27ea70f32fed7623391419ef2eacc447b65476eaabac224121ff68f1e51b9cf2bf07961a3280637d3231b39a0c159
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
## v0.2.0
|
2
|
+
### Jun 23, 2014
|
3
|
+
|
4
|
+
48a5715 2014-06-22 **Luca Guidi** Made Lotus::Action#content_type public
|
5
|
+
|
6
|
+
2d7b0cc 2014-06-22 **Luca Guidi** Let to specify a default format for all the requests that aren't strict about the requested Mime type (eg. `*/*`).
|
7
|
+
|
8
|
+
401c1af 2014-06-19 **Luca Guidi** [breaking] Raise error if Lotus::Controller::Configuration#format doesn't receive the proper argument. Let Lotus::Action::Mime#accept to work with registered mime types
|
9
|
+
|
10
|
+
028ec2e 2014-06-19 **Luca Guidi** Make Lotus::Action::Mime#format a public method
|
11
|
+
|
12
|
+
ce42cd4 2014-06-19 **Luca Guidi** Detect the asked mime type and return the corresponding format
|
13
|
+
|
14
|
+
87323ad 2014-06-19 **Luca Guidi** Let actions to detect accepted mime type and to return the correct format symbol. Configuration can now register mime types
|
15
|
+
|
16
|
+
adf0357 2014-06-18 **Krzysztof Zalewski** [breaking] Implement Action#format
|
17
|
+
|
18
|
+
328153b 2014-06-17 **Luca Guidi** Bump version to v0.2.0
|
19
|
+
|
20
|
+
b2e5c85 2014-06-17 **Luca Guidi** Depend on lotus-utils ~> 0.2
|
21
|
+
|
22
|
+
166a3c8 2014-06-17 **Luca Guidi** Controller.duplicate can accept nil controllers namespace
|
23
|
+
|
24
|
+
c11bc96 2014-06-17 **Luca Guidi** Lotus::Controller: .duplicate => .dup, .generate => .duplicate
|
25
|
+
|
26
|
+
9488c66 2014-06-16 **Luca Guidi** Gem: build only with lib/ and essential files
|
27
|
+
|
28
|
+
cd7038c 2014-06-16 **Luca Guidi** [breaking] Removed Lotus::Action::Throwable#throw in favor of #halt
|
29
|
+
|
30
|
+
c200e68 2014-06-16 **Luca Guidi** Pretty print exceptions in rack.errors
|
31
|
+
|
32
|
+
3c122b0 2014-06-13 **Krzysztof Zalewski** Reference exception in rack.errors
|
33
|
+
|
34
|
+
9e64c3f 2014-06-11 **Luca Guidi** Let Lotus::Controller.generate to set action_module
|
35
|
+
|
36
|
+
f28d7e3 2014-06-11 **Luca Guidi** Introducing Lotus::Controller.generate as shortcut for .duplicate and .configure
|
37
|
+
|
38
|
+
af217ea 2014-06-08 **Luca Guidi** [breaking] Use composition over inheritance for Lotus::Action::Params
|
39
|
+
|
40
|
+
47e86db 2014-06-08 **Luca Guidi** [breaking] Use composition over inheritance for Lotus::Action::CookieJar
|
41
|
+
|
42
|
+
5e2a4a7 2014-05-28 **Luca Guidi** Allow standalone actions to inherit configuration from the right framework. Added Configuration#modules in order to configure the additional modules to include by default
|
43
|
+
|
44
|
+
ceb7214 2014-05-28 **Luca Guidi** Better Ruby idioms
|
45
|
+
|
46
|
+
075f9c3 2014-05-28 **Luca Guidi** Use the proper level of encapsulation for Configuration
|
47
|
+
|
48
|
+
431970c 2014-05-27 **Luca Guidi** Ensure the right level of duplication for Lotus::Controller
|
49
|
+
|
50
|
+
ae49c57 2014-05-27 **Luca Guidi** [breaking] Keep independent copies of framework, controller and action configurations. Introduced in action_module for configuration.
|
51
|
+
|
52
|
+
c56683a 2014-05-27 **Luca Guidi** [breaking] Introduced configuration for Controller and Action
|
53
|
+
|
54
|
+
8d39557 2014-05-10 **Luca Guidi** Added support for Ruby 2.1.2
|
55
|
+
|
56
|
+
c2854b6 2014-04-27 **Luca Guidi** Make HTTP status messages compliant with IANA and Rack
|
57
|
+
|
58
|
+
c137c3f 2014-04-27 **Luca Guidi** Implemented Action.use, that let to use a Rack middleware as a before callback
|
59
|
+
|
60
|
+
eb86286 2014-04-20 **Damir Zekic** Replace `#throw` override with `#halt` method
|
61
|
+
|
62
|
+
6da21f9 2014-03-17 **Damir Zekic** Allow exception handling to be disabled
|
63
|
+
|
64
|
+
c0ccb72 2014-02-24 **Luca Guidi Added support for Ruby 2.1.1
|
65
|
+
|
66
|
+
## v0.1.0
|
67
|
+
### Feb 23, 2014
|
68
|
+
|
69
|
+
f750e4c 2014-02-22 **Luca Guidi** Moved .handled_exceptions from Action to Controller, so that the place where to configure the framework will be easier to find for developers.
|
70
|
+
|
71
|
+
1de2a27 2014-02-17 **Luca Guidi** Added Lotus::Action.handle_exception
|
72
|
+
|
73
|
+
fd9e080 2014-02-13 **Luca Guidi** Implemented Lotus::Action.accept, in order to restrict the access when a non supported mime type is requested
|
74
|
+
|
75
|
+
516983f 2014-02-13 **Luca Guidi** Implemented Lotus::Action#accept?
|
76
|
+
|
77
|
+
634719a 2014-02-13 **Luca Guidi** Changed auto content type policy
|
78
|
+
|
79
|
+
7cce354 2014-02-12 **Luca Guidi** Use @_env instead of the argument in Lotus::Action::Callable#call
|
80
|
+
|
81
|
+
a41b43d 2014-02-12 **Luca Guidi** Extracted constants for Lotus::Action::Params
|
82
|
+
|
83
|
+
6bdf55b 2014-01-31 **Luca Guidi** Make session support optional
|
84
|
+
|
85
|
+
29c5f8c 2014-01-31 **Luca Guidi** Make cookies support optional
|
86
|
+
|
87
|
+
0b36afb 2014-01-31 **Luca Guidi** Removed Lotus::HTTP::Request and Response
|
88
|
+
|
89
|
+
25b2bcf 2014-01-31 **Luca Guidi** Return serialized Rack response (Array) instead of the object. Lotus::Action::Redirect no longer depends on Response. Lotus::Action::CookieJar no longer depends on Response, but on headers.
|
90
|
+
|
91
|
+
b306f4f 2014-01-31 **Luca Guidi** Lotus::Action::Rack#session no longer depends on Request
|
92
|
+
|
93
|
+
9a44477 2014-01-31 **Luca Guidi** Lotus::Action::Mime no longer depends on Request
|
94
|
+
|
95
|
+
9b7f524 2014-01-31 **Luca Guidi** Lotus::Action::CookieJar logic for cookies extraction/set/get is no longer dependant on Request and Response.
|
96
|
+
|
97
|
+
fc6de40 2013-09-24 **Luca Guidi** Don't wrap body if respond to #each
|
98
|
+
|
99
|
+
ce46399 2013-09-24 **Luca Guidi** Introducing factory for Response
|
100
|
+
|
101
|
+
83adc9c 2013-08-07 **Luca Guidi** Ensure to wrap body for HTTP::Response
|
102
|
+
|
103
|
+
0a41bf8 2013-08-07 **Luca Guidi** Introducing Lotus::HTTP::Request/Response
|
104
|
+
|
105
|
+
c44d440 2013-07-12 **Luca Guidi** Integration tests for sessions
|
106
|
+
|
107
|
+
e62b355 2013-07-11 **Luca Guidi** Added automatic Mime Type capabilities
|
108
|
+
|
109
|
+
351eb2f 2013-07-11 **Luca Guidi** Split features in proper `Lotus::Action` submodules.
|
110
|
+
|
111
|
+
9d268df 2013-07-10 **Luca Guidi** Introducing throw facility, to stop the request flow immediately.
|
112
|
+
|
113
|
+
73af6d1 2013-07-09 **Luca Guidi** Integration tests with Lotus::Router
|
114
|
+
|
115
|
+
6938fae 2013-07-05 **Luca Guidi** Implemented cookies facilities.
|
116
|
+
|
117
|
+
69f4c62 2013-07-02 **Luca Guidi** Rack compatibility
|
118
|
+
|
119
|
+
13bd2d2 2013-06-28 **Luca Guidi** Implemented #redirect_to
|
120
|
+
|
121
|
+
5adbee1 2013-06-28 **Luca Guidi** Implemented sessions support
|
122
|
+
|
123
|
+
4bb794d 2013-06-28 **Luca Guidi** Implemented action callbacks
|
124
|
+
|
125
|
+
3b792dc 2013-06-25 **Luca Guidi** Introducing Lotus::Controller
|
126
|
+
|
127
|
+
d279c48 2013-06-25 **Luca Guidi** Initial mess
|
data/{LICENSE.txt → LICENSE.md}
RENAMED
File without changes
|
data/README.md
CHANGED
@@ -9,6 +9,7 @@ A Rack compatible Controller layer for [Lotus](http://lotusrb.org).
|
|
9
9
|
[](https://coveralls.io/r/lotus/controller)
|
10
10
|
[](https://codeclimate.com/github/lotus/controller)
|
11
11
|
[](https://gemnasium.com/lotus/controller)
|
12
|
+
[](http://inch-ci.org/github/lotus/controller)
|
12
13
|
|
13
14
|
## Contact
|
14
15
|
|
@@ -16,7 +17,8 @@ A Rack compatible Controller layer for [Lotus](http://lotusrb.org).
|
|
16
17
|
* Mailing List: http://lotusrb.org/mailing-list
|
17
18
|
* API Doc: http://rdoc.info/gems/lotus-controller
|
18
19
|
* Bugs/Issues: https://github.com/lotus/controller/issues
|
19
|
-
* Support: http://stackoverflow.com/questions/tagged/
|
20
|
+
* Support: http://stackoverflow.com/questions/tagged/lotus-ruby
|
21
|
+
* Chat: https://gitter.im/lotus/chat
|
20
22
|
|
21
23
|
## Rubies
|
22
24
|
|
@@ -44,7 +46,7 @@ $ gem install lotus-controller
|
|
44
46
|
|
45
47
|
## Usage
|
46
48
|
|
47
|
-
Lotus::Controller is a
|
49
|
+
Lotus::Controller is a micro library for web frameworks.
|
48
50
|
It works beautifully with [Lotus::Router](https://github.com/lotus/router), but it can be employed everywhere.
|
49
51
|
It's designed to be fast and testable.
|
50
52
|
|
@@ -262,7 +264,7 @@ You can define how a specific raised exception should be transformed in an HTTP
|
|
262
264
|
```ruby
|
263
265
|
class Show
|
264
266
|
include Lotus::Action
|
265
|
-
handle_exception RecordNotFound
|
267
|
+
handle_exception RecordNotFound => 404
|
266
268
|
|
267
269
|
def call(params)
|
268
270
|
@article = Article.find params[:id]
|
@@ -277,7 +279,9 @@ Exception policies can be defined globally, **before** the controllers/actions
|
|
277
279
|
are loaded.
|
278
280
|
|
279
281
|
```ruby
|
280
|
-
Lotus::Controller.
|
282
|
+
Lotus::Controller.configure do
|
283
|
+
handle_exception RecordNotFound => 404
|
284
|
+
end
|
281
285
|
|
282
286
|
class Show
|
283
287
|
include Lotus::Action
|
@@ -291,9 +295,36 @@ action = Show.new
|
|
291
295
|
action.call({id: 'unknown'}) # => [404, {}, ["Not Found"]]
|
292
296
|
```
|
293
297
|
|
298
|
+
This feature can be turned off globally, in a controller or in a single action.
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
Lotus::Controller.configure do
|
302
|
+
handle_exceptions false
|
303
|
+
end
|
304
|
+
|
305
|
+
# or
|
306
|
+
|
307
|
+
class ArticlesController
|
308
|
+
include Lotus::Controller
|
309
|
+
|
310
|
+
configure do
|
311
|
+
handle_exceptions false
|
312
|
+
end
|
313
|
+
|
314
|
+
action 'Show' do
|
315
|
+
def call(params)
|
316
|
+
@article = Article.find params[:id]
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
action = ArticlesController::Show.new
|
322
|
+
action.call({id: 'unknown'}) # => [404, {}, ["Not Found"]]
|
323
|
+
```
|
324
|
+
|
294
325
|
### Throwable HTTP statuses
|
295
326
|
|
296
|
-
When
|
327
|
+
When `#halt` is used with a valid HTTP code, it stops the execution and sets the proper status and body for the response:
|
297
328
|
|
298
329
|
```ruby
|
299
330
|
class Show
|
@@ -307,7 +338,7 @@ class Show
|
|
307
338
|
|
308
339
|
private
|
309
340
|
def authenticate!
|
310
|
-
|
341
|
+
halt 401 unless authenticated?
|
311
342
|
end
|
312
343
|
end
|
313
344
|
|
@@ -469,8 +500,26 @@ action.call({ article: { title: 'Hello' }}) # => [302, {'Location' => '/articles
|
|
469
500
|
|
470
501
|
### Mime types
|
471
502
|
|
472
|
-
Lotus::Action automatically sets the
|
473
|
-
|
503
|
+
Lotus::Action automatically sets the `Content-Type` header, according to the request.
|
504
|
+
|
505
|
+
```ruby
|
506
|
+
class Show
|
507
|
+
include Lotus::Action
|
508
|
+
|
509
|
+
def call(params)
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
action = Show.new
|
514
|
+
|
515
|
+
action.call({ 'HTTP_ACCEPT' => '*/*' }) # Content-Type "application/octet-stream"
|
516
|
+
action.format # :all
|
517
|
+
|
518
|
+
action.call({ 'HTTP_ACCEPT' => 'text/html' }) # Content-Type "text/html"
|
519
|
+
action.format # :html
|
520
|
+
```
|
521
|
+
|
522
|
+
However, you can force this value:
|
474
523
|
|
475
524
|
```ruby
|
476
525
|
class Show
|
@@ -478,12 +527,17 @@ class Show
|
|
478
527
|
|
479
528
|
def call(params)
|
480
529
|
# ...
|
481
|
-
self.
|
530
|
+
self.format = :json
|
482
531
|
end
|
483
532
|
end
|
484
533
|
|
485
534
|
action = Show.new
|
486
|
-
|
535
|
+
|
536
|
+
action.call({ 'HTTP_ACCEPT' => '*/*' }) # Content-Type "application/json"
|
537
|
+
action.format # :json
|
538
|
+
|
539
|
+
action.call({ 'HTTP_ACCEPT' => 'text/html' }) # Content-Type "application/json"
|
540
|
+
action.format # :json
|
487
541
|
```
|
488
542
|
|
489
543
|
You can restrict the accepted mime types:
|
@@ -517,6 +571,7 @@ class Show
|
|
517
571
|
accept?('text/html') # => true
|
518
572
|
accept?('application/xml') # => true
|
519
573
|
accept?('application/json') # => false
|
574
|
+
self.format # :html
|
520
575
|
|
521
576
|
|
522
577
|
|
@@ -525,8 +580,44 @@ class Show
|
|
525
580
|
accept?('text/html') # => true
|
526
581
|
accept?('application/xml') # => true
|
527
582
|
accept?('application/json') # => true
|
583
|
+
self.format # :html
|
584
|
+
end
|
585
|
+
end
|
586
|
+
```
|
587
|
+
|
588
|
+
Lotus::Controller is shipped with an extensive list of the most common mime types.
|
589
|
+
Also, you can register your own:
|
590
|
+
|
591
|
+
```ruby
|
592
|
+
Lotus::Controller.configure do
|
593
|
+
format custom: 'application/custom'
|
594
|
+
end
|
595
|
+
|
596
|
+
class Index
|
597
|
+
include Lotus::Action
|
598
|
+
|
599
|
+
def call(params)
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
action = Index.new
|
604
|
+
|
605
|
+
action.call({ 'HTTP_ACCEPT' => 'application/custom' }) # => Content-Type 'application/custom'
|
606
|
+
action.format # => :custom
|
607
|
+
|
608
|
+
class Show
|
609
|
+
include Lotus::Action
|
610
|
+
|
611
|
+
def call(params)
|
612
|
+
# ...
|
613
|
+
self.format = :custom
|
528
614
|
end
|
529
615
|
end
|
616
|
+
|
617
|
+
action = Show.new
|
618
|
+
|
619
|
+
action.call({ 'HTTP_ACCEPT' => '*/*' }) # => Content-Type 'application/custom'
|
620
|
+
action.format # => :custom
|
530
621
|
```
|
531
622
|
|
532
623
|
### No rendering, please
|
@@ -554,7 +645,7 @@ class ArticlesController
|
|
554
645
|
end
|
555
646
|
```
|
556
647
|
|
557
|
-
Which is a bit
|
648
|
+
Which is a bit verbose. Instead, just do:
|
558
649
|
|
559
650
|
```ruby
|
560
651
|
class ArticlesController
|
@@ -572,7 +663,7 @@ end
|
|
572
663
|
ArticlesController::Index.new.call({})
|
573
664
|
```
|
574
665
|
|
575
|
-
|
666
|
+
### Lotus::Router integration
|
576
667
|
|
577
668
|
While Lotus::Router works great with this framework, Lotus::Controller doesn't depend from it.
|
578
669
|
You, as developer, are free to choose your own routing system.
|
@@ -604,12 +695,165 @@ convenient fallback, you should know that it's the slower option. **Be sure of
|
|
604
695
|
loading your controllers before you initialize the router.**
|
605
696
|
|
606
697
|
|
607
|
-
|
698
|
+
### Rack integration
|
608
699
|
|
609
700
|
Lotus::Controller is compatible with Rack. However, it doesn't mount any middleware.
|
610
|
-
While a Lotus application's architecture is more web oriented, this framework is designed to build pure HTTP
|
701
|
+
While a Lotus application's architecture is more web oriented, this framework is designed to build pure HTTP endpoints.
|
702
|
+
|
703
|
+
### Rack middleware
|
704
|
+
|
705
|
+
Rack middleware can be configured globally in `config.ru`, but often they add an
|
706
|
+
unnecessary overhead for all those endpoints who aren't direct users of a
|
707
|
+
certain middleware. Think about a middleware to create sessions, where only
|
708
|
+
`SessionsController::Create` may be involved and the rest of the application
|
709
|
+
shouldn't pay the performance ticket of calling that middleware.
|
710
|
+
|
711
|
+
An action can employ one or more Rack middleware, with `.use`.
|
712
|
+
|
713
|
+
```ruby
|
714
|
+
require 'lotus/controller'
|
715
|
+
|
716
|
+
class SessionsController
|
717
|
+
include Lotus::Controller
|
718
|
+
|
719
|
+
action 'Create' do
|
720
|
+
use OmniAuth
|
721
|
+
|
722
|
+
def call(params)
|
723
|
+
# ...
|
724
|
+
end
|
725
|
+
end
|
726
|
+
end
|
727
|
+
```
|
728
|
+
|
729
|
+
```ruby
|
730
|
+
require 'lotus/controller'
|
731
|
+
|
732
|
+
class SessionsController
|
733
|
+
include Lotus::Controller
|
734
|
+
|
735
|
+
action 'Create' do
|
736
|
+
use XMiddleware.new('x', 123)
|
737
|
+
use YMiddleware.new
|
738
|
+
use ZMiddleware
|
739
|
+
|
740
|
+
def call(params)
|
741
|
+
# ...
|
742
|
+
end
|
743
|
+
end
|
744
|
+
end
|
745
|
+
```
|
746
|
+
|
747
|
+
### Configuration
|
748
|
+
|
749
|
+
Lotus::Controller can be configured with a DSL that determines its behavior.
|
750
|
+
It supports a few options:
|
751
|
+
|
752
|
+
```ruby
|
753
|
+
require 'lotus/controller'
|
754
|
+
|
755
|
+
Lotus::Controller.configure do
|
756
|
+
# Handle exceptions with HTTP statuses (true) or don't catch them (false)
|
757
|
+
# Argument: boolean, defaults to true
|
758
|
+
#
|
759
|
+
handle_exceptions true
|
760
|
+
|
761
|
+
# If the given exception is raised, return that HTTP status
|
762
|
+
# It can be used multiple times
|
763
|
+
# Argument: hash, empty by default
|
764
|
+
#
|
765
|
+
handle_exception ArgumentError => 404
|
766
|
+
|
767
|
+
# Configure which module to include when Lotus::Controller.action is used
|
768
|
+
# Argument: module, defaults to Lotus::Action
|
769
|
+
#
|
770
|
+
action_module MyApp::Action # module, defaults to Lotus::Action
|
771
|
+
|
772
|
+
# Register a format to mime type mapping
|
773
|
+
# Argument: hash, key: format symbol, value: mime type string, empty by default
|
774
|
+
#
|
775
|
+
format custom: 'application/custom'
|
776
|
+
|
777
|
+
# Configure the modules to be included/extended/prepended by default.
|
778
|
+
# Argument: proc, empty by default
|
779
|
+
#
|
780
|
+
modules do
|
781
|
+
include Lotus::Action::Sessions
|
782
|
+
prepend MyLibrary::Session::Store
|
783
|
+
end
|
784
|
+
end
|
785
|
+
```
|
786
|
+
|
787
|
+
All those global configurations can be overwritten at a finer grained level:
|
788
|
+
controllers. Each controller and action has its own copy of the global
|
789
|
+
configuration, so that changes are inherited from the top to the bottom, but
|
790
|
+
not bubbled up in the opposite direction.
|
791
|
+
|
792
|
+
```ruby
|
793
|
+
require 'lotus/controller'
|
794
|
+
|
795
|
+
Lotus::Controller.configure do
|
796
|
+
handle_exception ArgumentError => 404
|
797
|
+
end
|
798
|
+
|
799
|
+
class ArticlesController
|
800
|
+
include Lotus::Controller
|
801
|
+
|
802
|
+
configure do
|
803
|
+
handle_exceptions false
|
804
|
+
end
|
805
|
+
|
806
|
+
action 'Create' do
|
807
|
+
def call(params)
|
808
|
+
raise ArgumentError
|
809
|
+
end
|
810
|
+
end
|
811
|
+
end
|
812
|
+
|
813
|
+
class UsersController
|
814
|
+
include Lotus::Controller
|
815
|
+
|
816
|
+
action 'Create' do
|
817
|
+
def call(params)
|
818
|
+
raise ArgumentError
|
819
|
+
end
|
820
|
+
end
|
821
|
+
end
|
822
|
+
|
823
|
+
UsersController::Create.new.call({}) # => HTTP 400
|
824
|
+
|
825
|
+
ArticlesController::Create.new.call({})
|
826
|
+
# => raises ArgumentError because we set handle_exceptions to false
|
827
|
+
```
|
828
|
+
|
829
|
+
### Reusability
|
830
|
+
|
831
|
+
Lotus::Controller can be used as a singleton framework as seen in this README.
|
832
|
+
The application code includes `Lotus::Controller` or `Lotus::Action` directly
|
833
|
+
and the configuration is unique per Ruby process.
|
834
|
+
|
835
|
+
While this is convenient for tiny applications, it doesn't fit well for more
|
836
|
+
complex scenarios, where we want micro applications to coexist together.
|
837
|
+
|
838
|
+
```ruby
|
839
|
+
require 'lotus/controller'
|
840
|
+
|
841
|
+
module WebApp
|
842
|
+
Controller = Lotus::Controller.duplicate
|
843
|
+
end
|
844
|
+
|
845
|
+
module ApiApp
|
846
|
+
Controller = Lotus::Controller.duplicate(self) do
|
847
|
+
handle_exception ArgumentError => 400
|
848
|
+
end
|
849
|
+
end
|
850
|
+
```
|
851
|
+
|
852
|
+
The code above defines `WebApp::Controller` and `WebApp::Action`, to be used for
|
853
|
+
the `WebApp` endpoints, while `ApiApp::Controller` and `ApiApp::Action` have
|
854
|
+
a different configuration.
|
611
855
|
|
612
|
-
|
856
|
+
### Thread safety
|
613
857
|
|
614
858
|
An Action is **mutable**. When used without Lotus::Router, be sure to instantiate an
|
615
859
|
action for each request.
|