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 +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
|