lotus-router 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ded3effb55d8697f3a45666539825d205771161
4
- data.tar.gz: ac9b49d12b41b64e694998e4c663895f81279921
3
+ metadata.gz: df4ff4f67074d725ad10fc58dcdf1f647ad91255
4
+ data.tar.gz: 6d4fdaa8a6817a4acff0c9ccd0d2499205f4c0fb
5
5
  SHA512:
6
- metadata.gz: 1542eba77ef0f590dd88f9abe472760f09e14375796867dd031bd360bf2e19b4056c8b89c03b32bb45542a23616f6c502df2382a8dc19441b16b5eb0dc657223
7
- data.tar.gz: ea54e84f9c8507fd70d0c5c3e7f946930444d612dfc89012215d56a7ab55518658599dd0707dbb4da2358f1904d2717b27165f1ce9f77c9f40fdfc1626adb44e
6
+ metadata.gz: a9c7db01db9f64ff99083a34e610f56151264474b95619361bf143748d1298c84d97eef44212843c1de10c40e016d76d00f086fe17e3df1d2dcee8c62308a499
7
+ data.tar.gz: 73788060a4bc7b8062e4a0508bbe427bd32314cc4b5c003f04e8dc3674723ba2364aa00c3a70ec7a06428330b058e2e5ef60923c5c5cb49e74c0bc5f7808ae41
data/CHANGELOG.md CHANGED
@@ -1,45 +1,52 @@
1
- ## v0.1.1
2
- ### Jun 23, 2014
1
+ # Lotus::Router
2
+ Rack compatible HTTP router for Ruby
3
3
 
4
- 6f0ea8b 2014-06-12 **Luca Guidi** Introduced Lotus::Router#mount
5
- 8457e1c 2014-06-08 **Luca Guidi** Use composition over inheritance for Lotus::Routing::Resource::Options
6
- 9426099 2014-05-13 **Luca Guidi** Let specify a pattern for Lotus::Routing::EndpointResolver
7
- 340ce17 2014-05-10 **Luca Guidi** Enable Ruby 2.1.2 on Travis CI
8
- 42b83b8 2014-02-24 **Luca Guidi** Added support for Ruby 2.1.1
9
- 6a5daf9 2014-02-15 **Luca Guidi** Make Lotus::Routing::Endpoint::EndpointNotFound to inherit from StandardError, instead of Exception. This make it compatible with Rack::ShowExceptions.
4
+ ## v0.2.0 - 2014-12-23
5
+ ### Added
6
+ - [Luca Guidi & Alfonso Uceda Pompa] Introduced routes inspector for CLI
7
+ - [Luca Guidi & Janko Marohnić] Introduced body parser for JSON
8
+ - [Luca Guidi] Introduced request body parsers: they parse body and turn into params.
9
+ - [Fred Wu] Introduced Router#define
10
10
 
11
- ## v0.1.0
12
- ### Jan 23, 2014
11
+ ### Fixed
12
+ - [Luca Guidi] Fix for member/collection actions in RESTful resource(s): allow to take actions with a leading slash.
13
+ - [Janko Marohnić] Fix for nested namespaces and RESTful resource(s) under namespace. They were generating wrong route names.
14
+ - [Luca Guidi] Made InvalidRouteException to inherit from StandardError so it can be catched from anonymous `rescue` clause
15
+ - [Luca Guidi] Fix RESTful resource(s) to respect :only/:except options
13
16
 
14
- 594e332 2014-01-23 **Luca Guidi** Added support for OPTIONS HTTP verb
15
- 10af04b 2014-01-17 **Luca Guidi** Added Lotus::Routing::EndpointNotFound when a lazy endpoint can't be found
16
- 72165e5 2014-01-17 **Luca Guidi** Make action separator customizable via Lotus::Router options.
17
- ca7ea8d 2014-01-17 **Luca Guidi** Catch http_router exceptions and re-raise them with names under Lotus::Routing. This helps to have a stable public API.
18
- 3d678e3 2014-01-16 **Luca Guidi** Lotus::Router now encapsulates Lotus::Routing::HttpRouter, instead of directly inherit from HttpRouter. This will protect our public API against HttpRouter changes.
19
- 8e8f7f9 2014-01-16 **Luca Guidi** Lotus::Routing::Resource::CollectionAction use configurable controller and action name separator over the hardcoded value
20
- 0bc8e54 2014-01-10 **Luca Guidi** Implemented Lotus::Routing::Namespace#resource
21
- e134e5c 2014-01-08 **Luca Guidi** Simplify Lotus::Router public API: removed .draw and let .new to accept a block
22
- 815391a 2014-01-07 **Luca Guidi** When resetting the router, allow the default values for scheme, host and port to be reinitialized as http_router does
23
- bc763a8 2013-08-07 **Luca Guidi** Lotus::Routing::EndpointResolver now accepts options to inject namespace and suffix
24
- 153047f 2013-08-07 **Luca Guidi** Allow resolver and route class to be injected via options. Added options argument to .draw
25
- cd1128f 2013-08-07 **Luca Guidi** Lotus::EndpointResolver => Lotus::Routing::EndpointResolver
26
- 96a67c1 2013-07-09 **Luca Guidi** Return 404 for not found and 405 for unacceptable HTTP method
27
- 7450883 2013-07-05 **Luca Guidi** Allow non-finished Rack responses to be used
28
- aa92524 2013-06-24 **Luca Guidi** Ensure .draw to always return a Lotus::Router instance
29
- 30029af 2013-06-22 **Luca Guidi** Implemented lazy loading for endpoints
30
- 962fbdf 2013-06-21 **Luca Guidi** Implemented Lotus::Router.draw
31
- 982d95a 2013-06-20 **Luca Guidi** Gemified
32
- bac478a 2013-06-20 **Luca Guidi** Massive cleanup
33
- aaf46a1 2013-06-20 **Luca Guidi** Add support for resource
34
- 41ee67d 2013-06-20 **Luca Guidi** Drastically reduced LOCs :heart_eyes:
35
- 6b245bf 2013-06-19 **Luca Guidi** Support for resource's member and collection
36
- 727e997 2013-06-19 **Luca Guidi** Add support for namespaces
37
- 4950777 2013-06-18 **Luca Guidi** Added support for RESTful resources
38
- c494c85 2013-06-18 **Luca Guidi** Add support for POST, DELETE, PUT, PATCH, TRACE
39
- 71fb4a1 2013-06-17 **Luca Guidi** Routes constraints
40
- 86d696a 2013-06-17 **Luca Guidi** Named urls
41
- 423cf2c 2013-06-17 **Luca Guidi** Ensure redirect works properly
42
- 1ee662a 2013-06-17 **Luca Guidi** Run all the test suite
43
- e2382a0 2013-06-16 **Luca Guidi** Add support for Procs:
44
- f397aac 2013-06-16 **Luca Guidi** Implemented redirect
45
- dded0c5 2013-06-14 **Luca Guidi** Initial mess
17
+ ### Changed
18
+ - [Luca Guidi] Aligned naming conventions with Lotus::Controller: no more BooksController::Index. Use Books::Index instead.
19
+ - [Luca Guidi] Removed `:prefix` option for routes. Use `#namespace` blocks instead.
20
+ - [Janko Marohnić] Make 301 the default redirect status
21
+
22
+ ## v0.1.1 - 2014-06-23
23
+ ### Added
24
+ - [Luca Guidi] Introduced Lotus::Router#mount
25
+ - [Luca Guidi] Let specify a pattern for Lotus::Routing::EndpointResolver
26
+ - [Luca Guidi] Make Lotus::Routing::Endpoint::EndpointNotFound to inherit from StandardError, instead of Exception. This make it compatible with Rack::ShowExceptions.
27
+
28
+ ## v0.1.0 - 2014-01-23
29
+ ### Added
30
+ - [Luca Guidi] Official support for Ruby 2.1
31
+ - [Luca Guidi] Added support for OPTIONS HTTP verb
32
+ - [Luca Guidi] Added Lotus::Routing::EndpointNotFound when a lazy endpoint can't be found
33
+ - [Luca Guidi] Make action separator customizable via Lotus::Router options.
34
+ - [Luca Guidi] Catch http_router exceptions and re-raise them with names under Lotus::Routing. This helps to have a stable public API.
35
+ - [Luca Guidi] Lotus::Routing::Resource::CollectionAction use configurable controller and action name separator over the hardcoded value
36
+ - [Luca Guidi] Implemented Lotus::Routing::Namespace#resource
37
+ - [Luca Guidi] Lotus::Routing::EndpointResolver now accepts options to inject namespace and suffix
38
+ - [Luca Guidi] Allow resolver and route class to be injected via options
39
+ - [Luca Guidi] Return 404 for not found and 405 for unacceptable HTTP method
40
+ - [Luca Guidi] Allow non-finished Rack responses to be used
41
+ - [Luca Guidi] Implemented lazy loading for endpoints
42
+ - [Luca Guidi] Implemented Lotus::Router.new to take a block and define routes
43
+ - [Luca Guidi] Add support for resource
44
+ - [Luca Guidi] Support for resource's member and collection
45
+ - [Luca Guidi] Add support for namespaces
46
+ - [Luca Guidi] Added support for RESTful resources
47
+ - [Luca Guidi] Add support for POST, DELETE, PUT, PATCH, TRACE
48
+ - [Luca Guidi] Routes constraints
49
+ - [Luca Guidi] Named urls
50
+ - [Luca Guidi] Added support for Procs as endpoints
51
+ - [Luca Guidi] Implemented redirect
52
+ - [Luca Guidi] Basic routing
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Lotus::Router
2
2
 
3
- Rack compatible, lightweight and fast HTTP Router for [Lotus](http://lotusrb.org).
3
+ Rack compatible, lightweight and fast HTTP Router for Ruby and [Lotus](http://lotusrb.org).
4
4
 
5
5
  ## Status
6
6
 
@@ -22,7 +22,7 @@ Rack compatible, lightweight and fast HTTP Router for [Lotus](http://lotusrb.org
22
22
 
23
23
  ## Rubies
24
24
 
25
- __Lotus::Router__ supports Ruby (MRI) 2+
25
+ __Lotus::Router__ supports Ruby (MRI) 2+, JRuby 1.7 (with 2.0 mode)
26
26
 
27
27
 
28
28
  ## Installation
@@ -54,7 +54,7 @@ app = Lotus::Router.new do
54
54
  get '/', to: ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
55
55
  end
56
56
 
57
- Rack::Server.start app: app, Port: 2306
57
+ Rack::Server.start app: app, Port: 2300
58
58
  ```
59
59
 
60
60
  ## Usage
@@ -69,17 +69,17 @@ For the standalone usage, it supports neat features:
69
69
  ```ruby
70
70
  Lotus::Router.new do
71
71
  get '/', to: ->(env) { [200, {}, ['Hi!']] }
72
- get '/dashboard', to: DashboardController::Index
72
+ get '/dashboard', to: Dashboard::Index
73
73
  get '/rack-app', to: RackApp.new
74
74
  get '/flowers', to: 'flowers#index'
75
75
  get '/flowers/:id', to: 'flowers#show'
76
76
 
77
77
  redirect '/legacy', to: '/'
78
78
 
79
- mount Api::App, to: '/api'
79
+ mount Api::App, at: '/api'
80
80
 
81
81
  namespace 'admin' do
82
- get '/users', to: UsersController::Index
82
+ get '/users', to: Users::Index
83
83
  end
84
84
 
85
85
  resource 'identity' do
@@ -199,10 +199,6 @@ router.namespace 'animals' do
199
199
  end
200
200
  end
201
201
 
202
- # or
203
-
204
- router.get '/cats', prefix: '/animals/mammals', to:->(env) { [200, {}, ['Meow!']] }, as: :cats
205
-
206
202
  # and it generates:
207
203
 
208
204
  router.path(:animals_mammals_cats) # => "/animals/mammals/cats"
@@ -226,7 +222,7 @@ end
226
222
  2. `RackTwo` is initialized, because it respond to `#call`
227
223
  3. `RackThree` is used as it is (object), because it respond to `#call`
228
224
  4. That Proc is used as it is, because it respond to `#call`
229
- 5. That string is resolved as `DashboardController::Index` ([Lotus::Controller](https://github.com/lotus/controller) integration)
225
+ 5. That string is resolved as `Dashboard::Index` ([Lotus::Controller](https://github.com/lotus/controller) integration)
230
226
 
231
227
 
232
228
 
@@ -259,7 +255,7 @@ router.get '/lotus', to: 'rack_app' # it will map to RackApp.new
259
255
  It also supports Controller + Action syntax:
260
256
 
261
257
  ```ruby
262
- class FlowersController
258
+ module Flowers
263
259
  class Index
264
260
  def call(env)
265
261
  # ...
@@ -268,7 +264,7 @@ class FlowersController
268
264
  end
269
265
 
270
266
  router = Lotus::Router.new
271
- router.get '/flowers', to: 'flowers#index' # it will map to FlowersController::Index.new
267
+ router.get '/flowers', to: 'flowers#index' # it will map to Flowers::Index.new
272
268
  ```
273
269
 
274
270
 
@@ -280,7 +276,35 @@ router = Lotus::Router.new
280
276
  router.call(Rack::MockRequest.env_for('/unknown')).status # => 404
281
277
  ```
282
278
 
279
+ ### Controllers:
280
+
281
+ `Lotus::Router` has a special convention for controllers naming.
282
+ It allows to declare an action as an endpoint, with a special syntax: `<controller>#<action>`.
283
+
284
+ ```ruby
285
+ Lotus::Router.new do
286
+ get '/', to: 'welcome#index'
287
+ end
288
+ ```
289
+
290
+ In the example above, the router will look for the `Welcome::Index` action.
283
291
 
292
+ #### Namespaces
293
+
294
+ In applications where for maintainability or technical reasons, this convention
295
+ can't work, `Lotus::Router` can accept a `:namespace` option, which defines the
296
+ Ruby namespace where to look for actions.
297
+
298
+ For instance, given a Lotus full stack application called `Bookshelf`, the
299
+ controllers are available under `Bookshelf::Controllers`.
300
+
301
+ ```ruby
302
+ Lotus::Router.new(namespace: Bookshelf::Controllers) do
303
+ get '/', to: 'welcome#index'
304
+ end
305
+ ```
306
+
307
+ In the example above, the router will look for the `Bookshelf::Controllers::Welcome::Index` action.
284
308
 
285
309
  ### RESTful Resource:
286
310
 
@@ -302,42 +326,42 @@ It will map:
302
326
  <tr>
303
327
  <td>GET</td>
304
328
  <td>/identity</td>
305
- <td>IdentityController::Show</td>
329
+ <td>Identity::Show</td>
306
330
  <td>:show</td>
307
331
  <td>:identity</td>
308
332
  </tr>
309
333
  <tr>
310
334
  <td>GET</td>
311
335
  <td>/identity/new</td>
312
- <td>IdentityController::New</td>
336
+ <td>Identity::New</td>
313
337
  <td>:new</td>
314
338
  <td>:new_identity</td>
315
339
  </tr>
316
340
  <tr>
317
341
  <td>POST</td>
318
342
  <td>/identity</td>
319
- <td>IdentityController::Create</td>
343
+ <td>Identity::Create</td>
320
344
  <td>:create</td>
321
345
  <td>:identity</td>
322
346
  </tr>
323
347
  <tr>
324
348
  <td>GET</td>
325
349
  <td>/identity/edit</td>
326
- <td>IdentityController::Edit</td>
350
+ <td>Identity::Edit</td>
327
351
  <td>:edit</td>
328
352
  <td>:edit_identity</td>
329
353
  </tr>
330
354
  <tr>
331
355
  <td>PATCH</td>
332
356
  <td>/identity</td>
333
- <td>IdentityController::Update</td>
357
+ <td>Identity::Update</td>
334
358
  <td>:update</td>
335
359
  <td>:identity</td>
336
360
  </tr>
337
361
  <tr>
338
362
  <td>DELETE</td>
339
363
  <td>/identity</td>
340
- <td>IdentityController::Destroy</td>
364
+ <td>Identity::Destroy</td>
341
365
  <td>:destroy</td>
342
366
  <td>:identity</td>
343
367
  </tr>
@@ -361,11 +385,11 @@ If you need extra endpoints:
361
385
  router = Lotus::Router.new
362
386
  router.resource 'identity' do
363
387
  member do
364
- get '/avatar' # maps to IdentityController::Avatar
388
+ get 'avatar' # maps to Identity::Avatar
365
389
  end
366
390
 
367
391
  collection do
368
- get '/authorizations' # maps to IdentityController::Authorizations
392
+ get 'authorizations' # maps to Identity::Authorizations
369
393
  end
370
394
  end
371
395
 
@@ -395,49 +419,49 @@ It will map:
395
419
  <tr>
396
420
  <td>GET</td>
397
421
  <td>/flowers</td>
398
- <td>FlowersController::Index</td>
422
+ <td>Flowers::Index</td>
399
423
  <td>:index</td>
400
424
  <td>:flowers</td>
401
425
  </tr>
402
426
  <tr>
403
427
  <td>GET</td>
404
428
  <td>/flowers/:id</td>
405
- <td>FlowersController::Show</td>
429
+ <td>Flowers::Show</td>
406
430
  <td>:show</td>
407
431
  <td>:flowers</td>
408
432
  </tr>
409
433
  <tr>
410
434
  <td>GET</td>
411
435
  <td>/flowers/new</td>
412
- <td>FlowersController::New</td>
436
+ <td>Flowers::New</td>
413
437
  <td>:new</td>
414
438
  <td>:new_flowers</td>
415
439
  </tr>
416
440
  <tr>
417
441
  <td>POST</td>
418
442
  <td>/flowers</td>
419
- <td>FlowersController::Create</td>
443
+ <td>Flowers::Create</td>
420
444
  <td>:create</td>
421
445
  <td>:flowers</td>
422
446
  </tr>
423
447
  <tr>
424
448
  <td>GET</td>
425
449
  <td>/flowers/:id/edit</td>
426
- <td>FlowersController::Edit</td>
450
+ <td>Flowers::Edit</td>
427
451
  <td>:edit</td>
428
452
  <td>:edit_flowers</td>
429
453
  </tr>
430
454
  <tr>
431
455
  <td>PATCH</td>
432
456
  <td>/flowers/:id</td>
433
- <td>FlowersController::Update</td>
457
+ <td>Flowers::Update</td>
434
458
  <td>:update</td>
435
459
  <td>:flowers</td>
436
460
  </tr>
437
461
  <tr>
438
462
  <td>DELETE</td>
439
463
  <td>/flowers/:id</td>
440
- <td>FlowersController::Destroy</td>
464
+ <td>Flowers::Destroy</td>
441
465
  <td>:destroy</td>
442
466
  <td>:flowers</td>
443
467
  </tr>
@@ -470,10 +494,11 @@ If you need extra endpoints:
470
494
  router = Lotus::Router.new
471
495
  router.resources 'flowers' do
472
496
  member do
473
- get '/toggle' # maps to FlowersController::Toggle
497
+ get 'toggle' # maps to Flowers::Toggle
474
498
  end
499
+
475
500
  collection do
476
- get '/search' # maps to FlowersController::Search
501
+ get 'search' # maps to Flowers::Search
477
502
  end
478
503
  end
479
504
 
data/lib/lotus/router.rb CHANGED
@@ -42,26 +42,13 @@ module Lotus
42
42
  # require 'lotus/router'
43
43
  #
44
44
  # router = Lotus::Router.new do
45
- # get '/', to: 'articles#show' # => ArticlesController::Show
45
+ # get '/', to: 'articles#show' # => Articles::Show
46
46
  # end
47
47
  #
48
48
  # # This is a builtin feature for a Lotus::Controller convention.
49
49
  #
50
50
  #
51
51
  #
52
- # @example Specify a prefix with `:prefix`
53
- # require 'lotus/router'
54
- #
55
- # endpoint = ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
56
- # router = Lotus::Router.new do
57
- # get '/welcome', to: endpoint, prefix: 'dashboard' # => '/dashboard/welcome'
58
- # end
59
- #
60
- # # :prefix isn't mandatory for the default resolver (`Lotus::Routing::EndpointResolver.new`),
61
- # # This behavior can be changed by passing a custom resolver to `Lotus::Router#initialize`
62
- #
63
- #
64
- #
65
52
  # @example Specify a named route with `:as`
66
53
  # require 'lotus/router'
67
54
  #
@@ -98,6 +85,8 @@ module Lotus
98
85
  # (defaults to `Lotus::Routing::Route`)
99
86
  # @option options [String] :action_separator the separator between controller
100
87
  # and action name (eg. 'dashboard#show', where '#' is the :action_separator)
88
+ # @option options [Array<Symbol,String,Object #mime_types, parse>] :parsers
89
+ # the body parsers for mime types
101
90
  #
102
91
  # @param blk [Proc] the optional block to define the routes
103
92
  #
@@ -105,7 +94,7 @@ module Lotus
105
94
  #
106
95
  # @since 0.1.0
107
96
  #
108
- # @example
97
+ # @example Basic example
109
98
  # require 'lotus/router'
110
99
  #
111
100
  # endpoint = ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
@@ -118,22 +107,135 @@ module Lotus
118
107
  # router = Lotus::Router.new do
119
108
  # get '/', to: endpoint
120
109
  # end
110
+ #
111
+ # @example Body parsers
112
+ # require 'json'
113
+ # require 'lotus/router'
114
+ #
115
+ # # It parses JSON body and makes the attributes available to the params
116
+ #
117
+ # endpoint = ->(env) { [200, {},[env['router.params'].inspect]] }
118
+ #
119
+ # router = Lotus::Router.new(parsers: [:json]) do
120
+ # patch '/books/:id', to: endpoint
121
+ # end
122
+ #
123
+ # # From the shell
124
+ #
125
+ # curl http://localhost:2300/books/1 \
126
+ # -H "Content-Type: application/json" \
127
+ # -H "Accept: application/json" \
128
+ # -d '{"published":"true"}' \
129
+ # -X PATCH
130
+ #
131
+ # # It returns
132
+ #
133
+ # [200, {}, ["{:published=>\"true\",:id=>\"1\"}"]]
134
+ #
135
+ # @example Custom body parser
136
+ # require 'lotus/router'
137
+ #
138
+ # class XmlParser
139
+ # def mime_types
140
+ # ['application/xml', 'text/xml']
141
+ # end
142
+ #
143
+ # # Parse body and return a Hash
144
+ # def parse(body)
145
+ # # ...
146
+ # end
147
+ # end
148
+ #
149
+ # # It parses XML body and makes the attributes available to the params
150
+ #
151
+ # endpoint = ->(env) { [200, {},[env['router.params'].inspect]] }
152
+ #
153
+ # router = Lotus::Router.new(parsers: [XmlParser.new]) do
154
+ # patch '/authors/:id', to: endpoint
155
+ # end
156
+ #
157
+ # # From the shell
158
+ #
159
+ # curl http://localhost:2300/authors/1 \
160
+ # -H "Content-Type: application/xml" \
161
+ # -H "Accept: application/xml" \
162
+ # -d '<name>LG</name>' \
163
+ # -X PATCH
164
+ #
165
+ # # It returns
166
+ #
167
+ # [200, {}, ["{:name=>\"LG\",:id=>\"1\"}"]]
121
168
  def initialize(options = {}, &blk)
122
169
  @router = Routing::HttpRouter.new(options)
170
+ define(&blk)
171
+ end
172
+
173
+ # Returns self
174
+ #
175
+ # This is a duck-typing trick for compatibility with `Lotus::Application`.
176
+ # It's used by `Lotus::Routing::RoutesInspector` to inspect both apps and
177
+ # routers.
178
+ #
179
+ # @return [self]
180
+ #
181
+ # @since 0.2.0
182
+ # @api private
183
+ def routes
184
+ self
185
+ end
186
+
187
+ # To support defining routes in the `define` wrapper.
188
+ #
189
+ # @param blk [Proc] the block to define the routes
190
+ #
191
+ # @return [Lotus::Routing::Route]
192
+ #
193
+ # @since 0.2.0
194
+ #
195
+ # @example In Lotus framework
196
+ # class Application < Lotus::Application
197
+ # configure do
198
+ # routes 'config/routes'
199
+ # end
200
+ # end
201
+ #
202
+ # # In `config/routes`
203
+ #
204
+ # define do
205
+ # get # ...
206
+ # end
207
+ def define(&blk)
123
208
  instance_eval(&blk) if block_given?
124
209
  end
125
210
 
211
+ # Check if there are defined routes
212
+ #
213
+ # @return [TrueClass,FalseClass] the result of the check
214
+ #
215
+ # @since 0.2.0
216
+ # @api private
217
+ #
218
+ # @example
219
+ #
220
+ # router = Lotus::Router.new
221
+ # router.defined? # => false
222
+ #
223
+ # router = Lotus::Router.new { get '/', to: ->(env) { } }
224
+ # router.defined? # => true
225
+ def defined?
226
+ @router.routes.any?
227
+ end
228
+
126
229
  # Defines a route that accepts a GET request for the given path.
127
230
  #
128
231
  # @param path [String] the relative URL to be matched
129
232
  #
130
233
  # @param options [Hash] the options to customize the route
131
234
  # @option options [String,Proc,Class,Object#call] :to the endpoint
132
- # @option options [String] :prefix an optional path prefix
133
235
  #
134
236
  # @param blk [Proc] the anonymous proc to be used as endpoint for the route
135
237
  #
136
- # @return [Lotus::Roting::Route] this may vary according to the :route
238
+ # @return [Lotus::Routing::Route] this may vary according to the :route
137
239
  # option passed to the constructor
138
240
  #
139
241
  # @since 0.1.0
@@ -198,17 +300,6 @@ module Lotus
198
300
  # router.path(:lotus) # => "/lotus"
199
301
  # router.url(:lotus) # => "https://lotusrb.org/lotus"
200
302
  #
201
- # @example Prefixed routes
202
- # require 'lotus/router'
203
- #
204
- # router = Lotus::Router.new
205
- # router.get '/cats',
206
- # prefix: '/animals/mammals',
207
- # to: ->(env) { [200, {}, ['Meow!']] },
208
- # as: :cats
209
- #
210
- # router.path(:animals_mammals_cats) # => "/animals/mammals/cats"
211
- #
212
303
  # @example Duck typed endpoints (Rack compatible objects)
213
304
  # require 'lotus/router'
214
305
  #
@@ -236,18 +327,18 @@ module Lotus
236
327
  # @example Duck typed endpoints (string: controller + action)
237
328
  # require 'lotus/router'
238
329
  #
239
- # class FlowersController
330
+ # module Flowers
240
331
  # class Index
241
332
  # def call(env)
242
333
  # # ...
243
334
  # end
244
335
  # end
245
- # end
336
+ # end
246
337
  #
247
338
  # router = Lotus::Router.new
248
339
  # router.get '/flowers', to: 'flowers#index'
249
340
  #
250
- # # It will map to FlowersController::Index.new, which is the
341
+ # # It will map to Flowers::Index.new, which is the
251
342
  # # Lotus::Controller convention.
252
343
  def get(path, options = {}, &blk)
253
344
  @router.get(path, options, &blk)
@@ -259,11 +350,10 @@ module Lotus
259
350
  #
260
351
  # @param options [Hash] the options to customize the route
261
352
  # @option options [String,Proc,Class,Object#call] :to the endpoint
262
- # @option options [String] :prefix an optional path prefix
263
353
  #
264
354
  # @param blk [Proc] the anonymous proc to be used as endpoint for the route
265
355
  #
266
- # @return [Lotus::Roting::Route] this may vary according to the :route
356
+ # @return [Lotus::Routing::Route] this may vary according to the :route
267
357
  # option passed to the constructor
268
358
  #
269
359
  # @see Lotus::Router#get
@@ -279,11 +369,10 @@ module Lotus
279
369
  #
280
370
  # @param options [Hash] the options to customize the route
281
371
  # @option options [String,Proc,Class,Object#call] :to the endpoint
282
- # @option options [String] :prefix an optional path prefix
283
372
  #
284
373
  # @param blk [Proc] the anonymous proc to be used as endpoint for the route
285
374
  #
286
- # @return [Lotus::Roting::Route] this may vary according to the :route
375
+ # @return [Lotus::Routing::Route] this may vary according to the :route
287
376
  # option passed to the constructor
288
377
  #
289
378
  # @see Lotus::Router#get
@@ -299,11 +388,10 @@ module Lotus
299
388
  #
300
389
  # @param options [Hash] the options to customize the route
301
390
  # @option options [String,Proc,Class,Object#call] :to the endpoint
302
- # @option options [String] :prefix an optional path prefix
303
391
  #
304
392
  # @param blk [Proc] the anonymous proc to be used as endpoint for the route
305
393
  #
306
- # @return [Lotus::Roting::Route] this may vary according to the :route
394
+ # @return [Lotus::Routing::Route] this may vary according to the :route
307
395
  # option passed to the constructor
308
396
  #
309
397
  # @see Lotus::Router#get
@@ -319,11 +407,10 @@ module Lotus
319
407
  #
320
408
  # @param options [Hash] the options to customize the route
321
409
  # @option options [String,Proc,Class,Object#call] :to the endpoint
322
- # @option options [String] :prefix an optional path prefix
323
410
  #
324
411
  # @param blk [Proc] the anonymous proc to be used as endpoint for the route
325
412
  #
326
- # @return [Lotus::Roting::Route] this may vary according to the :route
413
+ # @return [Lotus::Routing::Route] this may vary according to the :route
327
414
  # option passed to the constructor
328
415
  #
329
416
  # @see Lotus::Router#get
@@ -339,11 +426,10 @@ module Lotus
339
426
  #
340
427
  # @param options [Hash] the options to customize the route
341
428
  # @option options [String,Proc,Class,Object#call] :to the endpoint
342
- # @option options [String] :prefix an optional path prefix
343
429
  #
344
430
  # @param blk [Proc] the anonymous proc to be used as endpoint for the route
345
431
  #
346
- # @return [Lotus::Roting::Route] this may vary according to the :route
432
+ # @return [Lotus::Routing::Route] this may vary according to the :route
347
433
  # option passed to the constructor
348
434
  #
349
435
  # @see Lotus::Router#get
@@ -359,11 +445,10 @@ module Lotus
359
445
  #
360
446
  # @param options [Hash] the options to customize the route
361
447
  # @option options [String,Proc,Class,Object#call] :to the endpoint
362
- # @option options [String] :prefix an optional path prefix
363
448
  #
364
449
  # @param blk [Proc] the anonymous proc to be used as endpoint for the route
365
450
  #
366
- # @return [Lotus::Roting::Route] this may vary according to the :route
451
+ # @return [Lotus::Routing::Route] this may vary according to the :route
367
452
  # option passed to the constructor
368
453
  #
369
454
  # @see Lotus::Router#get
@@ -377,7 +462,7 @@ module Lotus
377
462
  #
378
463
  # @param path [String] the path that needs to be redirected
379
464
  # @param options [Hash] the options to customize the redirect behavior
380
- # @option options [Fixnum] the HTTP status to return (defaults to `302`)
465
+ # @option options [Fixnum] the HTTP status to return (defaults to `301`)
381
466
  #
382
467
  # @return [Lotus::Routing::Route] the generated route.
383
468
  # This may vary according to the `:route` option passed to the initializer
@@ -391,7 +476,7 @@ module Lotus
391
476
  #
392
477
  # Lotus::Router.new do
393
478
  # redirect '/legacy', to: '/new_endpoint'
394
- # redirect '/legacy2', to: '/new_endpoint2', code: 301
479
+ # redirect '/legacy2', to: '/new_endpoint2', code: 302
395
480
  # end
396
481
  #
397
482
  # @example
@@ -400,15 +485,16 @@ module Lotus
400
485
  # router = Lotus::Router.new
401
486
  # router.redirect '/legacy', to: '/new_endpoint'
402
487
  def redirect(path, options = {}, &endpoint)
403
- get(path).redirect @router.find(options), options[:code] || 302
488
+ get(path).redirect @router.find(options), options[:code] || 301
404
489
  end
405
490
 
406
491
  # Defines a Ruby block: all the routes defined within it will be namespaced
407
- # with the given prefix.
492
+ # with the given relative path.
408
493
  #
409
494
  # Namespaces blocks can be nested multiple times.
410
495
  #
411
- # @param prefix [String] the path prefix
496
+ # @param namespace [String] the relative path where the nested routes will
497
+ # be mounted
412
498
  # @param blk [Proc] the block that defines the resources
413
499
  #
414
500
  # @return [Lotus::Routing::Namespace] the generated namespace.
@@ -424,10 +510,6 @@ module Lotus
424
510
  # namespace 'trees' do
425
511
  # get '/sequoia', to: endpoint # => '/trees/sequoia'
426
512
  # end
427
- #
428
- # # equivalent to
429
- #
430
- # get '/sequoia', to: endpoint, prefix: 'trees' # => '/trees/sequoia'
431
513
  # end
432
514
  #
433
515
  # @example Nested namespaces
@@ -448,8 +530,8 @@ module Lotus
448
530
  # router.namespace 'trees' do
449
531
  # get '/sequoia', to: endpoint # => '/trees/sequoia'
450
532
  # end
451
- def namespace(prefix, &blk)
452
- Routing::Namespace.new(self, prefix, &blk)
533
+ def namespace(namespace, &blk)
534
+ Routing::Namespace.new(self, namespace, &blk)
453
535
  end
454
536
 
455
537
  # Defines a set of named routes for a single RESTful resource.
@@ -480,16 +562,16 @@ module Lotus
480
562
  #
481
563
  # # It generates:
482
564
  # #
483
- # # +--------+----------------+-----------------------------+----------+----------------+
484
- # # | Verb | Path | Action | Name | Named Route |
485
- # # +--------+----------------+-----------------------------+----------+----------------+
486
- # # | GET | /identity | IdentityController::Show | :show | :identity |
487
- # # | GET | /identity/new | IdentityController::New | :new | :new_identity |
488
- # # | POST | /identity | IdentityController::Create | :create | :identity |
489
- # # | GET | /identity/edit | IdentityController::Edit | :edit | :edit_identity |
490
- # # | PATCH | /identity | IdentityController::Update | :update | :identity |
491
- # # | DELETE | /identity | IdentityController::Destroy | :destroy | :identity |
492
- # # +--------+----------------+-----------------------------+----------+----------------+
565
+ # # +--------+----------------+-------------------+----------+----------------+
566
+ # # | Verb | Path | Action | Name | Named Route |
567
+ # # +--------+----------------+-------------------+----------+----------------+
568
+ # # | GET | /identity | Identity::Show | :show | :identity |
569
+ # # | GET | /identity/new | Identity::New | :new | :new_identity |
570
+ # # | POST | /identity | Identity::Create | :create | :identity |
571
+ # # | GET | /identity/edit | Identity::Edit | :edit | :edit_identity |
572
+ # # | PATCH | /identity | Identity::Update | :update | :identity |
573
+ # # | DELETE | /identity | Identity::Destroy | :destroy | :identity |
574
+ # # +--------+----------------+-------------------+----------+----------------+
493
575
  #
494
576
  #
495
577
  #
@@ -502,13 +584,13 @@ module Lotus
502
584
  #
503
585
  # # It generates:
504
586
  # #
505
- # # +--------+----------------+-----------------------------+----------+----------------+
506
- # # | Verb | Path | Action | Name | Named Route |
507
- # # +--------+----------------+-----------------------------+----------+----------------+
508
- # # | GET | /identity | IdentityController::Show | :show | :identity |
509
- # # | GET | /identity/new | IdentityController::New | :new | :new_identity |
510
- # # | POST | /identity | IdentityController::Create | :create | :identity |
511
- # # +--------+----------------+-----------------------------+----------+----------------+
587
+ # # +--------+----------------+------------------+----------+----------------+
588
+ # # | Verb | Path | Action | Name | Named Route |
589
+ # # +--------+----------------+------------------+----------+----------------+
590
+ # # | GET | /identity | Identity::Show | :show | :identity |
591
+ # # | GET | /identity/new | Identity::New | :new | :new_identity |
592
+ # # | POST | /identity | Identity::Create | :create | :identity |
593
+ # # +--------+----------------+------------------+----------+----------------+
512
594
  #
513
595
  #
514
596
  #
@@ -521,13 +603,13 @@ module Lotus
521
603
  #
522
604
  # # It generates:
523
605
  # #
524
- # # +--------+----------------+-----------------------------+----------+----------------+
525
- # # | Verb | Path | Action | Name | Named Route |
526
- # # +--------+----------------+-----------------------------+----------+----------------+
527
- # # | GET | /identity | IdentityController::Show | :show | :identity |
528
- # # | GET | /identity/new | IdentityController::New | :new | :new_identity |
529
- # # | POST | /identity | IdentityController::Create | :create | :identity |
530
- # # +--------+----------------+-----------------------------+----------+----------------+
606
+ # # +--------+----------------+------------------+----------+----------------+
607
+ # # | Verb | Path | Action | Name | Named Route |
608
+ # # +--------+----------------+------------------+----------+----------------+
609
+ # # | GET | /identity | Identity::Show | :show | :identity |
610
+ # # | GET | /identity/new | Identity::New | :new | :new_identity |
611
+ # # | POST | /identity | Identity::Create | :create | :identity |
612
+ # # +--------+----------------+------------------+----------+----------------+
531
613
  #
532
614
  #
533
615
  #
@@ -544,11 +626,11 @@ module Lotus
544
626
  #
545
627
  # # It generates:
546
628
  # #
547
- # # +--------+--------------------+------------------------------+------+--------------------+
548
- # # | Verb | Path | Action | Name | Named Route |
549
- # # +--------+--------------------+------------------------------+------+--------------------+
550
- # # | PATCH | /identity/activate | IdentityController::Activate | | :activate_identity |
551
- # # +--------+--------------------+------------------------------+------+--------------------+
629
+ # # +--------+--------------------+--------------------+------+--------------------+
630
+ # # | Verb | Path | Action | Name | Named Route |
631
+ # # +--------+--------------------+--------------------+------+--------------------+
632
+ # # | PATCH | /identity/activate | Identity::Activate | | :activate_identity |
633
+ # # +--------+--------------------+--------------------+------+--------------------+
552
634
  #
553
635
  #
554
636
  #
@@ -565,11 +647,11 @@ module Lotus
565
647
  #
566
648
  # # It generates:
567
649
  # #
568
- # # +------+----------------+--------------------------+------+----------------+
569
- # # | Verb | Path | Action | Name | Named Route |
570
- # # +------+----------------+--------------------------+------+----------------+
571
- # # | GET | /identity/keys | IdentityController::Keys | | :keys_identity |
572
- # # +------+----------------+--------------------------+------+----------------+
650
+ # # +------+----------------+----------------+------+----------------+
651
+ # # | Verb | Path | Action | Name | Named Route |
652
+ # # +------+----------------+----------------+------+----------------+
653
+ # # | GET | /identity/keys | Identity::Keys | | :keys_identity |
654
+ # # +------+----------------+----------------+------+----------------+
573
655
  def resource(name, options = {}, &blk)
574
656
  Routing::Resource.new(self, name, options.merge(separator: @router.action_separator), &blk)
575
657
  end
@@ -602,17 +684,17 @@ module Lotus
602
684
  #
603
685
  # # It generates:
604
686
  # #
605
- # # +--------+--------------------+-----------------------------+----------+----------------+
606
- # # | Verb | Path | Action | Name | Named Route |
607
- # # +--------+--------------------+-----------------------------+----------+----------------+
608
- # # | GET | /articles | ArticlesController::Index | :index | :articles |
609
- # # | GET | /articles/:id | ArticlesController::Show | :show | :articles |
610
- # # | GET | /articles/new | ArticlesController::New | :new | :new_articles |
611
- # # | POST | /articles | ArticlesController::Create | :create | :articles |
612
- # # | GET | /articles/:id/edit | ArticlesController::Edit | :edit | :edit_articles |
613
- # # | PATCH | /articles/:id | ArticlesController::Update | :update | :articles |
614
- # # | DELETE | /articles/:id | ArticlesController::Destroy | :destroy | :articles |
615
- # # +--------+--------------------+-----------------------------+----------+----------------+
687
+ # # +--------+--------------------+-------------------+----------+----------------+
688
+ # # | Verb | Path | Action | Name | Named Route |
689
+ # # +--------+--------------------+-------------------+----------+----------------+
690
+ # # | GET | /articles | Articles::Index | :index | :articles |
691
+ # # | GET | /articles/:id | Articles::Show | :show | :articles |
692
+ # # | GET | /articles/new | Articles::New | :new | :new_articles |
693
+ # # | POST | /articles | Articles::Create | :create | :articles |
694
+ # # | GET | /articles/:id/edit | Articles::Edit | :edit | :edit_articles |
695
+ # # | PATCH | /articles/:id | Articles::Update | :update | :articles |
696
+ # # | DELETE | /articles/:id | Articles::Destroy | :destroy | :articles |
697
+ # # +--------+--------------------+-------------------+----------+----------------+
616
698
  #
617
699
  #
618
700
  #
@@ -625,11 +707,11 @@ module Lotus
625
707
  #
626
708
  # # It generates:
627
709
  # #
628
- # # +------+-----------+---------------------------+--------+-------------+
629
- # # | Verb | Path | Action | Name | Named Route |
630
- # # +------+-----------+---------------------------+--------+-------------+
631
- # # | GET | /articles | ArticlesController::Index | :index | :articles |
632
- # # +------+-----------+---------------------------+--------+-------------+
710
+ # # +------+-----------+-----------------+--------+-------------+
711
+ # # | Verb | Path | Action | Name | Named Route |
712
+ # # +------+-----------+-----------------+--------+-------------+
713
+ # # | GET | /articles | Articles::Index | :index | :articles |
714
+ # # +------+-----------+-----------------+--------+-------------+
633
715
  #
634
716
  #
635
717
  #
@@ -642,15 +724,15 @@ module Lotus
642
724
  #
643
725
  # # It generates:
644
726
  # #
645
- # # +--------+--------------------+-----------------------------+----------+----------------+
646
- # # | Verb | Path | Action | Name | Named Route |
647
- # # +--------+--------------------+-----------------------------+----------+----------------+
648
- # # | GET | /articles | ArticlesController::Index | :index | :articles |
649
- # # | GET | /articles/:id | ArticlesController::Show | :show | :articles |
650
- # # | GET | /articles/new | ArticlesController::New | :new | :new_articles |
651
- # # | POST | /articles | ArticlesController::Create | :create | :articles |
652
- # # | DELETE | /articles/:id | ArticlesController::Destroy | :destroy | :articles |
653
- # # +--------+--------------------+-----------------------------+----------+----------------+
727
+ # # +--------+--------------------+-------------------+----------+----------------+
728
+ # # | Verb | Path | Action | Name | Named Route |
729
+ # # +--------+--------------------+-------------------+----------+----------------+
730
+ # # | GET | /articles | Articles::Index | :index | :articles |
731
+ # # | GET | /articles/:id | Articles::Show | :show | :articles |
732
+ # # | GET | /articles/new | Articles::New | :new | :new_articles |
733
+ # # | POST | /articles | Articles::Create | :create | :articles |
734
+ # # | DELETE | /articles/:id | Articles::Destroy | :destroy | :articles |
735
+ # # +--------+--------------------+-------------------+----------+----------------+
654
736
  #
655
737
  #
656
738
  #
@@ -667,11 +749,11 @@ module Lotus
667
749
  #
668
750
  # # It generates:
669
751
  # #
670
- # # +--------+-----------------------+-----------------------------+------+-------------------+
671
- # # | Verb | Path | Action | Name | Named Route |
672
- # # +--------+-----------------------+-----------------------------+------+-------------------+
673
- # # | PATCH | /articles/:id/publish | ArticlesController::Publish | | :publish_articles |
674
- # # +--------+-----------------------+-----------------------------+------+-------------------+
752
+ # # +--------+-----------------------+-------------------+------+-------------------+
753
+ # # | Verb | Path | Action | Name | Named Route |
754
+ # # +--------+-----------------------+-------------------+------+-------------------+
755
+ # # | PATCH | /articles/:id/publish | Articles::Publish | | :publish_articles |
756
+ # # +--------+-----------------------+-------------------+------+-------------------+
675
757
  #
676
758
  #
677
759
  #
@@ -688,11 +770,11 @@ module Lotus
688
770
  #
689
771
  # # It generates:
690
772
  # #
691
- # # +------+------------------+----------------------------+------+------------------+
692
- # # | Verb | Path | Action | Name | Named Route |
693
- # # +------+------------------+----------------------------+------+------------------+
694
- # # | GET | /articles/search | ArticlesController::Search | | :search_articles |
695
- # # +------+------------------+----------------------------+------+------------------+
773
+ # # +------+------------------+------------------+------+------------------+
774
+ # # | Verb | Path | Action | Name | Named Route |
775
+ # # +------+------------------+------------------+------+------------------+
776
+ # # | GET | /articles/search | Articles::Search | | :search_articles |
777
+ # # +------+------------------+------------------+------+------------------+
696
778
  def resources(name, options = {}, &blk)
697
779
  Routing::Resources.new(self, name, options.merge(separator: @router.action_separator), &blk)
698
780
  end
@@ -708,7 +790,7 @@ module Lotus
708
790
  #
709
791
  # @param app [#call] a class or an object that responds to #call
710
792
  # @param options [Hash] the options to customize the mount
711
- # @option options [:at] the path prefix where to mount the app
793
+ # @option options [:at] the relative path where to mount the app
712
794
  #
713
795
  # @since 0.1.1
714
796
  #
@@ -762,7 +844,7 @@ module Lotus
762
844
  # end
763
845
  # end
764
846
  #
765
- # class DashboardController
847
+ # module Dashboard
766
848
  # class Index
767
849
  # def call(env)
768
850
  # end
@@ -781,7 +863,7 @@ module Lotus
781
863
  # # 2. RackTwo is initialized, because it respond to #call
782
864
  # # 3. RackThree is used as it is (object), because it respond to #call
783
865
  # # 4. That Proc is used as it is, because it respond to #call
784
- # # 5. That string is resolved as DashboardController::Index (Lotus::Controller)
866
+ # # 5. That string is resolved as Dashboard::Index (Lotus::Controller)
785
867
  def mount(app, options)
786
868
  @router.mount(app, options)
787
869
  end
@@ -850,5 +932,31 @@ module Lotus
850
932
  def url(route, *args)
851
933
  @router.url(route, *args)
852
934
  end
935
+
936
+ # Returns an routes inspector
937
+ #
938
+ # @since 0.2.0
939
+ #
940
+ # @see Lotus::Routing::RoutesInspector
941
+ #
942
+ # @example
943
+ # require 'lotus/router'
944
+ #
945
+ # router = Lotus::Router.new do
946
+ # get '/', to: 'home#index'
947
+ # get '/login', to: 'sessions#new', as: :login
948
+ # post '/login', to: 'sessions#create'
949
+ # delete '/logout', to: 'sessions#destroy', as: :logout
950
+ # end
951
+ #
952
+ # puts router.inspector
953
+ # # => GET, HEAD / Home::Index
954
+ # login GET, HEAD /login Sessions::New
955
+ # POST /login Sessions::Create
956
+ # logout GET, HEAD /logout Sessions::Destroy
957
+ def inspector
958
+ require 'lotus/routing/routes_inspector'
959
+ Routing::RoutesInspector.new(@router.routes)
960
+ end
853
961
  end
854
962
  end