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 +4 -4
- data/CHANGELOG.md +49 -42
- data/README.md +55 -30
- data/lib/lotus/router.rb +234 -126
- data/lib/lotus/router/version.rb +1 -1
- data/lib/lotus/routing/endpoint.rb +38 -2
- data/lib/lotus/routing/endpoint_resolver.rb +24 -73
- data/lib/lotus/routing/http_router.rb +8 -1
- data/lib/lotus/routing/namespace.rb +3 -3
- data/lib/lotus/routing/parsers.rb +71 -0
- data/lib/lotus/routing/parsing/json_parser.rb +17 -0
- data/lib/lotus/routing/parsing/parser.rb +43 -0
- data/lib/lotus/routing/resource.rb +4 -4
- data/lib/lotus/routing/resource/action.rb +34 -36
- data/lib/lotus/routing/resources/action.rb +13 -6
- data/lib/lotus/routing/route.rb +9 -0
- data/lib/lotus/routing/routes_inspector.rb +168 -0
- data/lotus-router.gemspec +5 -4
- metadata +19 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df4ff4f67074d725ad10fc58dcdf1f647ad91255
|
4
|
+
data.tar.gz: 6d4fdaa8a6817a4acff0c9ccd0d2499205f4c0fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9c7db01db9f64ff99083a34e610f56151264474b95619361bf143748d1298c84d97eef44212843c1de10c40e016d76d00f086fe17e3df1d2dcee8c62308a499
|
7
|
+
data.tar.gz: 73788060a4bc7b8062e4a0508bbe427bd32314cc4b5c003f04e8dc3674723ba2364aa00c3a70ec7a06428330b058e2e5ef60923c5c5cb49e74c0bc5f7808ae41
|
data/CHANGELOG.md
CHANGED
@@ -1,45 +1,52 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Lotus::Router
|
2
|
+
Rack compatible HTTP router for Ruby
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
12
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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:
|
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:
|
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,
|
79
|
+
mount Api::App, at: '/api'
|
80
80
|
|
81
81
|
namespace 'admin' do
|
82
|
-
get '/users', to:
|
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 `
|
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
|
-
|
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
|
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>
|
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>
|
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>
|
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>
|
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>
|
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>
|
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
|
-
|
388
|
+
get 'avatar' # maps to Identity::Avatar
|
365
389
|
end
|
366
390
|
|
367
391
|
collection do
|
368
|
-
get '
|
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>
|
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>
|
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>
|
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>
|
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>
|
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>
|
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>
|
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 '
|
497
|
+
get 'toggle' # maps to Flowers::Toggle
|
474
498
|
end
|
499
|
+
|
475
500
|
collection do
|
476
|
-
get '
|
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' # =>
|
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::
|
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
|
-
#
|
330
|
+
# module Flowers
|
240
331
|
# class Index
|
241
332
|
# def call(env)
|
242
333
|
# # ...
|
243
334
|
# end
|
244
335
|
# end
|
245
|
-
#
|
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
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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 `
|
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:
|
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] ||
|
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
|
-
#
|
492
|
+
# with the given relative path.
|
408
493
|
#
|
409
494
|
# Namespaces blocks can be nested multiple times.
|
410
495
|
#
|
411
|
-
# @param
|
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(
|
452
|
-
Routing::Namespace.new(self,
|
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
|
485
|
-
# #
|
486
|
-
# # | GET | /identity |
|
487
|
-
# # | GET | /identity/new |
|
488
|
-
# # | POST | /identity |
|
489
|
-
# # | GET | /identity/edit |
|
490
|
-
# # | PATCH | /identity |
|
491
|
-
# # | DELETE | /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
|
507
|
-
# #
|
508
|
-
# # | GET | /identity |
|
509
|
-
# # | GET | /identity/new |
|
510
|
-
# # | POST | /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
|
526
|
-
# #
|
527
|
-
# # | GET | /identity |
|
528
|
-
# # | GET | /identity/new |
|
529
|
-
# # | POST | /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
|
549
|
-
# #
|
550
|
-
# # | PATCH | /identity/activate |
|
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
|
570
|
-
# #
|
571
|
-
# # | GET | /identity/keys |
|
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
|
607
|
-
# #
|
608
|
-
# # | GET | /articles |
|
609
|
-
# # | GET | /articles/:id |
|
610
|
-
# # | GET | /articles/new |
|
611
|
-
# # | POST | /articles |
|
612
|
-
# # | GET | /articles/:id/edit |
|
613
|
-
# # | PATCH | /articles/:id |
|
614
|
-
# # | DELETE | /articles/:id |
|
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
|
630
|
-
# #
|
631
|
-
# # | GET | /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
|
647
|
-
# #
|
648
|
-
# # | GET | /articles |
|
649
|
-
# # | GET | /articles/:id |
|
650
|
-
# # | GET | /articles/new |
|
651
|
-
# # | POST | /articles |
|
652
|
-
# # | DELETE | /articles/:id |
|
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
|
672
|
-
# #
|
673
|
-
# # | PATCH | /articles/:id/publish |
|
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
|
693
|
-
# #
|
694
|
-
# # | GET | /articles/search |
|
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
|
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
|
-
#
|
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
|
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
|