lotus-router 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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