hanami-router 1.3.2 → 2.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -3
  3. data/README.md +192 -154
  4. data/hanami-router.gemspec +23 -20
  5. data/lib/hanami/middleware/body_parser.rb +17 -13
  6. data/lib/hanami/middleware/body_parser/class_interface.rb +56 -56
  7. data/lib/hanami/middleware/body_parser/errors.rb +7 -4
  8. data/lib/hanami/middleware/body_parser/json_parser.rb +5 -3
  9. data/lib/hanami/middleware/error.rb +16 -0
  10. data/lib/hanami/router.rb +262 -149
  11. data/lib/hanami/router/version.rb +3 -1
  12. data/lib/hanami/routing.rb +193 -0
  13. data/lib/hanami/routing/endpoint.rb +122 -104
  14. data/lib/hanami/routing/endpoint_resolver.rb +20 -16
  15. data/lib/hanami/routing/prefix.rb +102 -0
  16. data/lib/hanami/routing/recognized_route.rb +40 -26
  17. data/lib/hanami/routing/resource.rb +9 -7
  18. data/lib/hanami/routing/resource/action.rb +58 -33
  19. data/lib/hanami/routing/resource/nested.rb +4 -1
  20. data/lib/hanami/routing/resource/options.rb +3 -1
  21. data/lib/hanami/routing/resources.rb +6 -4
  22. data/lib/hanami/routing/resources/action.rb +11 -6
  23. data/lib/hanami/routing/routes_inspector.rb +22 -20
  24. data/lib/hanami/routing/scope.rb +112 -0
  25. metadata +47 -25
  26. data/lib/hanami-router.rb +0 -1
  27. data/lib/hanami/routing/error.rb +0 -7
  28. data/lib/hanami/routing/force_ssl.rb +0 -212
  29. data/lib/hanami/routing/http_router.rb +0 -220
  30. data/lib/hanami/routing/http_router_monkey_patch.rb +0 -38
  31. data/lib/hanami/routing/namespace.rb +0 -98
  32. data/lib/hanami/routing/parsers.rb +0 -113
  33. data/lib/hanami/routing/parsing/json_parser.rb +0 -33
  34. data/lib/hanami/routing/parsing/parser.rb +0 -61
  35. data/lib/hanami/routing/route.rb +0 -71
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e266df3fe2a5a32cea6a813fb6806810e752a3b2c78e1699a7ff78b90d597ae0
4
- data.tar.gz: 02617f20d71d090f2cecf7af765d3b03af487aa38d5da6c8c2f993773ce0174a
3
+ metadata.gz: aa833cfc2bc3e9d0f796738dc3c8c649f001afdee01662094f387aabc3afa496
4
+ data.tar.gz: c7f7314b65e6ab36fee40e4a8d2037b4086c0f5a6ae9ddf5002e4d42007826b9
5
5
  SHA512:
6
- metadata.gz: 1ed45a0595d20e01dd302164d0e5f9855b57eff54e75febf6bf34a26d05f9c544af825f7407bfaec468d11a4bb024e29d9edcb193dfd2bef08ce3e8495ac23f1
7
- data.tar.gz: 7ca9c8a1a8c14e2895196be0aaaa49e1e2f951a4fdea9bd64602237bf82c87607d525ce0660694c8ceea148ba35a87c227f1893307f8b42a876e87bda80579ab
6
+ metadata.gz: fd5ca50885e99302376c13c8d0ccdc48db6e59b97d64ca8c3740f976ecfdf0687c6c2f841273286b92af16d880051216e8888353ef24e92285f918c31d67a65f
7
+ data.tar.gz: b9107bc2be7289893809d2837c37fb5cc6642715239b6c510b76af47a86c71daa186f167f8890a2f7b59292be1eeadaf0aca90bb358e2951563b0414c17245c7
@@ -1,10 +1,21 @@
1
1
  # Hanami::Router
2
2
  Rack compatible HTTP router for Ruby
3
3
 
4
- ## v1.3.2 - 2019-02-13
4
+ ## v2.0.0.alpha1 - 2019-01-30
5
5
  ### Added
6
- - [Luca Guidi] Official support for Ruby: MRI 2.7
7
- - [Luca Guidi] Support `rack` 2.1
6
+ - [Luca Guidi] Introduce `Hanami::Router#scope` to support single routing tier for Hanami
7
+ - [Semyon Pupkov] Added `inflector:` option for `Hanami::Router#initialize` based on `dry-inflector`
8
+
9
+ ### Changed
10
+ - [Luca Guidi] Drop support for Ruby: MRI 2.3, and 2.4.
11
+ - [Luca Guidi] Renamed `Hanami::Router#namespace` => `#prefix`
12
+ - [Gustavo Caso] Remove body cleanup for `HEAD` requests
13
+ - [Semyon Pupkov] Remove the ability to force SSL (`force_ssl:` option for `Hanami::Router#initialize`)
14
+ - [Gustavo Caso] Remove router body parsers (`parsers:` option for `Hanami::Router#initialize`)
15
+ - [Luca Guidi] Globbed path requires named capture (was `get "/files/*"`, now is `get "/files/*names"`)
16
+ - [Luca Guidi] Router is frozen after initialization
17
+ - [Luca Guidi] All the code base respects the frozen string pragma
18
+ - [Luca Guidi] `Hanami::Router#initialize` requires `configuration:` option if routes endpoints are `Hanami::Action` subclasses
8
19
 
9
20
  ## v1.3.1 - 2019-01-18
10
21
  ### Added
data/README.md CHANGED
@@ -5,7 +5,7 @@ Rack compatible, lightweight and fast HTTP Router for Ruby and [Hanami](http://h
5
5
  ## Status
6
6
 
7
7
  [![Gem Version](https://badge.fury.io/rb/hanami-router.svg)](https://badge.fury.io/rb/hanami-router)
8
- [![Build Status](https://ci.hanamirb.org/api/badges/hanami/router/status.svg)](https://ci.hanamirb.org/hanami/router)
8
+ [![TravisCI](https://travis-ci.org/hanami/router.svg?branch=master)](https://travis-ci.org/hanami/router)
9
9
  [![CircleCI](https://circleci.com/gh/hanami/router/tree/master.svg?style=svg)](https://circleci.com/gh/hanami/router/tree/master)
10
10
  [![Test Coverage](https://codecov.io/gh/hanami/router/branch/master/graph/badge.svg)](https://codecov.io/gh/hanami/router)
11
11
  [![Depfu](https://badges.depfu.com/badges/5f6b8e8fa3b0d082539f0b0f84d55960/overview.svg)](https://depfu.com/github/hanami/router?project=Bundler)
@@ -22,7 +22,7 @@ Rack compatible, lightweight and fast HTTP Router for Ruby and [Hanami](http://h
22
22
 
23
23
  ## Rubies
24
24
 
25
- __Hanami::Router__ supports Ruby (MRI) 2.3+, JRuby 9.1.5.0+
25
+ __Hanami::Router__ supports Ruby (MRI) 2.5+
26
26
 
27
27
 
28
28
  ## Installation
@@ -47,14 +47,23 @@ $ gem install hanami-router
47
47
 
48
48
  ## Getting Started
49
49
 
50
+ Create a file named `config.ru`
51
+
50
52
  ```ruby
51
- require 'hanami/router'
53
+ # frozen_string_literal: true
54
+ require "hanami/router"
52
55
 
53
56
  app = Hanami::Router.new do
54
- get '/', to: ->(env) { [200, {}, ['Welcome to Hanami::Router!']] }
57
+ get "/", to: ->(env) { [200, {}, ["Welcome to Hanami!"]] }
55
58
  end
56
59
 
57
- Rack::Server.start app: app, Port: 2300
60
+ run app
61
+ ```
62
+
63
+ From the shell:
64
+
65
+ ```shell
66
+ $ bundle exec rackup
58
67
  ```
59
68
 
60
69
  ## Usage
@@ -68,38 +77,38 @@ For the standalone usage, it supports neat features:
68
77
 
69
78
  ```ruby
70
79
  Hanami::Router.new do
71
- root to: ->(env) { [200, {}, ['Hello']] }
72
- get '/lambda', to: ->(env) { [200, {}, ['World']] }
73
- get '/dashboard', to: Dashboard::Index
74
- get '/rack-app', to: RackApp.new
75
- get '/flowers', to: 'flowers#index'
76
- get '/flowers/:id', to: 'flowers#show'
80
+ root to: ->(env) { [200, {}, ["Hello"]] }
81
+ get "/lambda", to: ->(env) { [200, {}, ["World"]] }
82
+ get "/dashboard", to: Dashboard::Index
83
+ get "/rack-app", to: RackApp.new
84
+ get "/flowers", to: "flowers#index"
85
+ get "/flowers/:id", to: "flowers#show"
77
86
 
78
- redirect '/legacy', to: '/'
87
+ redirect "/legacy", to: "/"
79
88
 
80
- mount Api::App, at: '/api'
89
+ mount Api::App, at: "/api"
81
90
 
82
- namespace 'admin' do
83
- get '/users', to: Users::Index
91
+ prefix "admin" do
92
+ get "/users", to: Users::Index
84
93
  end
85
94
 
86
- resource 'identity' do
95
+ resource "identity" do
87
96
  member do
88
- get '/avatar'
97
+ get "/avatar"
89
98
  end
90
99
 
91
100
  collection do
92
- get '/api_keys'
101
+ get "/api_keys"
93
102
  end
94
103
  end
95
104
 
96
- resources 'robots' do
105
+ resources "robots" do
97
106
  member do
98
- patch '/activate'
107
+ patch "/activate"
99
108
  end
100
109
 
101
110
  collection do
102
- get '/search'
111
+ get "/search"
103
112
  end
104
113
  end
105
114
  end
@@ -110,8 +119,9 @@ end
110
119
  ### Fixed string matching:
111
120
 
112
121
  ```ruby
113
- router = Hanami::Router.new
114
- router.get '/hanami', to: ->(env) { [200, {}, ['Hello from Hanami!']] }
122
+ Hanami::Router.new do
123
+ get "/hanami", to: ->(env) { [200, {}, ["Hello from Hanami!"]] }
124
+ end
115
125
  ```
116
126
 
117
127
 
@@ -119,8 +129,9 @@ router.get '/hanami', to: ->(env) { [200, {}, ['Hello from Hanami!']] }
119
129
  ### String matching with variables:
120
130
 
121
131
  ```ruby
122
- router = Hanami::Router.new
123
- router.get '/flowers/:id', to: ->(env) { [200, {}, ["Hello from Flower no. #{ env['router.params'][:id] }!"]] }
132
+ Hanami::Router.new do
133
+ get "/flowers/:id", to: ->(env) { [200, {}, ["Hello from Flower no. #{ env["router.params"][:id] }!"]] }
134
+ end
124
135
  ```
125
136
 
126
137
 
@@ -128,8 +139,9 @@ router.get '/flowers/:id', to: ->(env) { [200, {}, ["Hello from Flower no. #{ en
128
139
  ### Variables Constraints:
129
140
 
130
141
  ```ruby
131
- router = Hanami::Router.new
132
- router.get '/flowers/:id', id: /\d+/, to: ->(env) { [200, {}, [":id must be a number!"]] }
142
+ Hanami::Router.new do
143
+ get "/flowers/:id", id: /\d+/, to: ->(env) { [200, {}, [":id must be a number!"]] }
144
+ end
133
145
  ```
134
146
 
135
147
 
@@ -137,8 +149,9 @@ router.get '/flowers/:id', id: /\d+/, to: ->(env) { [200, {}, [":id must be a nu
137
149
  ### String matching with globbing:
138
150
 
139
151
  ```ruby
140
- router = Hanami::Router.new
141
- router.get '/*', to: ->(env) { [200, {}, ["This is catch all: #{ env['router.params'].inspect }!"]] }
152
+ Hanami::Router.new do
153
+ get "/*match", to: ->(env) { [200, {}, ["This is catch all: #{ env["router.params"].inspect }!"]] }
154
+ end
142
155
  ```
143
156
 
144
157
 
@@ -146,8 +159,9 @@ router.get '/*', to: ->(env) { [200, {}, ["This is catch all: #{ env['router.par
146
159
  ### String matching with optional tokens:
147
160
 
148
161
  ```ruby
149
- router = Hanami::Router.new
150
- router.get '/hanami(.:format)' to: ->(env) { [200, {}, ["You've requested #{ env['router.params'][:format] }!"]] }
162
+ Hanami::Router.new do
163
+ get "/hanami(.:format)" to: ->(env) { [200, {}, ["You"ve requested #{ env["router.params"][:format] }!"]] }
164
+ end
151
165
  ```
152
166
 
153
167
 
@@ -155,15 +169,17 @@ router.get '/hanami(.:format)' to: ->(env) { [200, {}, ["You've requested #{ env
155
169
  ### Support for the most common HTTP methods:
156
170
 
157
171
  ```ruby
158
- router = Hanami::Router.new
159
- endpoint = ->(env) { [200, {}, ['Hello from Hanami!']] }
172
+ endpoint = ->(env) { [200, {}, ["Hello from Hanami!"]] }
160
173
 
161
- router.get '/hanami', to: endpoint
162
- router.post '/hanami', to: endpoint
163
- router.put '/hanami', to: endpoint
164
- router.patch '/hanami', to: endpoint
165
- router.delete '/hanami', to: endpoint
166
- router.trace '/hanami', to: endpoint
174
+ Hanami::Router.new do
175
+ get "/hanami", to: endpoint
176
+ post "/hanami", to: endpoint
177
+ put "/hanami", to: endpoint
178
+ patch "/hanami", to: endpoint
179
+ delete "/hanami", to: endpoint
180
+ trace "/hanami", to: endpoint
181
+ options "/hanami", to: endpoint
182
+ end
167
183
  ```
168
184
 
169
185
 
@@ -171,8 +187,9 @@ router.trace '/hanami', to: endpoint
171
187
  ### Root:
172
188
 
173
189
  ```ruby
174
- router = Hanami::Router.new
175
- router.root to: ->(env) { [200, {}, ['Hello from Hanami!']] }
190
+ Hanami::Router.new do
191
+ root to: ->(env) { [200, {}, ["Hello from Hanami!"]] }
192
+ end
176
193
  ```
177
194
 
178
195
 
@@ -180,9 +197,10 @@ router.root to: ->(env) { [200, {}, ['Hello from Hanami!']] }
180
197
  ### Redirect:
181
198
 
182
199
  ```ruby
183
- router = Hanami::Router.new
184
- router.get '/redirect_destination', to: ->(env) { [200, {}, ['Redirect destination!']] }
185
- router.redirect '/legacy', to: '/redirect_destination'
200
+ Hanami::Router.new do
201
+ get "/redirect_destination", to: ->(env) { [200, {}, ["Redirect destination!"]] }
202
+ redirect "/legacy", to: "/redirect_destination"
203
+ end
186
204
  ```
187
205
 
188
206
 
@@ -190,8 +208,9 @@ router.redirect '/legacy', to: '/redirect_destination'
190
208
  ### Named routes:
191
209
 
192
210
  ```ruby
193
- router = Hanami::Router.new(scheme: 'https', host: 'hanamirb.org')
194
- router.get '/hanami', to: ->(env) { [200, {}, ['Hello from Hanami!']] }, as: :hanami
211
+ router = Hanami::Router.new(scheme: "https", host: "hanamirb.org") do
212
+ get "/hanami", to: ->(env) { [200, {}, ["Hello from Hanami!"]] }, as: :hanami
213
+ end
195
214
 
196
215
  router.path(:hanami) # => "/hanami"
197
216
  router.url(:hanami) # => "https://hanamirb.org/hanami"
@@ -199,13 +218,14 @@ router.url(:hanami) # => "https://hanamirb.org/hanami"
199
218
 
200
219
 
201
220
 
202
- ### Namespaced routes:
221
+ ### Prefixed routes:
203
222
 
204
223
  ```ruby
205
- router = Hanami::Router.new
206
- router.namespace 'animals' do
207
- namespace 'mammals' do
208
- get '/cats', to: ->(env) { [200, {}, ['Meow!']] }, as: :cats
224
+ router = Hanami::Router.new do
225
+ prefix "animals" do
226
+ prefix "mammals" do
227
+ get "/cats", to: ->(env) { [200, {}, ["Meow!"]] }, as: :cats
228
+ end
209
229
  end
210
230
  end
211
231
 
@@ -220,11 +240,11 @@ router.path(:animals_mammals_cats) # => "/animals/mammals/cats"
220
240
 
221
241
  ```ruby
222
242
  Hanami::Router.new do
223
- mount RackOne, at: '/rack1'
224
- mount RackTwo, at: '/rack2'
225
- mount RackThree.new, at: '/rack3'
226
- mount ->(env) {[200, {}, ['Rack Four']]}, at: '/rack4'
227
- mount 'dashboard#index', at: '/dashboard'
243
+ mount RackOne, at: "/rack1"
244
+ mount RackTwo, at: "/rack2"
245
+ mount RackThree.new, at: "/rack3"
246
+ mount ->(env) {[200, {}, ["Rack Four"]]}, at: "/rack4"
247
+ mount "dashboard#index", at: "/dashboard"
228
248
  end
229
249
  ```
230
250
 
@@ -241,11 +261,12 @@ end
241
261
  Everything that responds to `#call` is invoked as it is:
242
262
 
243
263
  ```ruby
244
- router = Hanami::Router.new
245
- router.get '/hanami', to: ->(env) { [200, {}, ['Hello from Hanami!']] }
246
- router.get '/middleware', to: Middleware
247
- router.get '/rack-app', to: RackApp.new
248
- router.get '/method', to: ActionControllerSubclass.action(:new)
264
+ Hanami::Router.new do
265
+ get "/hanami", to: ->(env) { [200, {}, ["Hello from Hanami!"]] }
266
+ get "/middleware", to: Middleware
267
+ get "/rack-app", to: RackApp.new
268
+ get "/method", to: ActionControllerSubclass.action(:new)
269
+ end
249
270
  ```
250
271
 
251
272
 
@@ -258,23 +279,25 @@ class RackApp
258
279
  end
259
280
  end
260
281
 
261
- router = Hanami::Router.new
262
- router.get '/hanami', to: 'rack_app' # it will map to RackApp.new
282
+ Hanami::Router.new do
283
+ get "/hanami", to: "rack_app" # it will map to RackApp.new
284
+ end
263
285
  ```
264
286
 
265
287
  It also supports Controller + Action syntax:
266
288
 
267
289
  ```ruby
268
290
  module Flowers
269
- class Index
270
- def call(env)
291
+ class Index < Hanami::Action
292
+ def handle(*)
271
293
  # ...
272
294
  end
273
295
  end
274
296
  end
275
297
 
276
- router = Hanami::Router.new
277
- router.get '/flowers', to: 'flowers#index' # it will map to Flowers::Index.new
298
+ Hanami::Router.new do
299
+ get "/flowers", to: "flowers#index" # it will map to Flowers::Index.new
300
+ end
278
301
  ```
279
302
 
280
303
 
@@ -283,7 +306,7 @@ router.get '/flowers', to: 'flowers#index' # it will map to Flowers::Index.new
283
306
 
284
307
  ```ruby
285
308
  router = Hanami::Router.new
286
- router.call(Rack::MockRequest.env_for('/unknown')).status # => 404
309
+ router.call(Rack::MockRequest.env_for("/unknown")).status # => 404
287
310
  ```
288
311
 
289
312
  ### Controllers:
@@ -293,7 +316,7 @@ It allows to declare an action as an endpoint, with a special syntax: `<controll
293
316
 
294
317
  ```ruby
295
318
  Hanami::Router.new do
296
- get '/', to: 'welcome#index'
319
+ get "/", to: "welcome#index"
297
320
  end
298
321
  ```
299
322
 
@@ -310,7 +333,7 @@ controllers are available under `Bookshelf::Controllers`.
310
333
 
311
334
  ```ruby
312
335
  Hanami::Router.new(namespace: Bookshelf::Controllers) do
313
- get '/', to: 'welcome#index'
336
+ get "/", to: "welcome#index"
314
337
  end
315
338
  ```
316
339
 
@@ -319,8 +342,9 @@ In the example above, the router will look for the `Bookshelf::Controllers::Welc
319
342
  ### RESTful Resource:
320
343
 
321
344
  ```ruby
322
- router = Hanami::Router.new
323
- router.resource 'identity'
345
+ Hanami::Router.new do
346
+ resource "identity"
347
+ end
324
348
  ```
325
349
 
326
350
  It will map:
@@ -380,41 +404,46 @@ It will map:
380
404
  If you don't need all the default endpoints, just do:
381
405
 
382
406
  ```ruby
383
- router = Hanami::Router.new
384
- router.resource 'identity', only: [:edit, :update]
407
+ Hanami::Router.new do
408
+ resource "identity", only: [:edit, :update]
409
+ end
385
410
 
386
411
  #### which is equivalent to:
387
412
 
388
- router.resource 'identity', except: [:show, :new, :create, :destroy]
413
+ Hanami::Router.new do
414
+ resource "identity", except: [:show, :new, :create, :destroy]
415
+ end
389
416
  ```
390
417
 
391
418
 
392
419
  If you need extra endpoints:
393
420
 
394
421
  ```ruby
395
- router = Hanami::Router.new
396
- router.resource 'identity' do
397
- member do
398
- get 'avatar' # maps to Identity::Avatar
399
- end
422
+ router = Hanami::Router.new do
423
+ resource "identity" do
424
+ member do
425
+ get "avatar" # maps to Identity::Avatar
426
+ end
400
427
 
401
- collection do
402
- get 'authorizations' # maps to Identity::Authorizations
403
- end
404
- end
428
+ collection do
429
+ get "authorizations" # maps to Identity::Authorizations
430
+ end
431
+ end
432
+ end
405
433
 
406
- router.path(:avatar_identity) # => /identity/avatar
407
- router.path(:authorizations_identity) # => /identity/authorizations
434
+ router.path(:avatar_identity) # => "/identity/avatar"
435
+ router.path(:authorizations_identity) # => "/identity/authorizations"
408
436
  ```
409
437
 
410
438
 
411
439
  Configure controller:
412
440
 
413
441
  ```ruby
414
- router = Hanami::Router.new
415
- router.resource 'profile', controller: 'identity'
442
+ router = Hanami::Router.new do
443
+ resource "profile", controller: "identity"
444
+ end
416
445
 
417
- router.path(:profile) # => /profile # Will route to Identity::Show
446
+ router.path(:profile) # => "/profile" # Will route to Identity::Show
418
447
  ```
419
448
 
420
449
  #### Nested Resources
@@ -422,20 +451,21 @@ router.path(:profile) # => /profile # Will route to Identity::Show
422
451
  We can nest resource(s):
423
452
 
424
453
  ```ruby
425
- router = Hanami::Router.new
426
- router.resource :identity do
427
- resource :avatar
428
- resources :api_keys
429
- end
454
+ router = Hanami::Router.new do
455
+ resource :identity do
456
+ resource :avatar
457
+ resources :api_keys
458
+ end
459
+ end
430
460
 
431
- router.path(:identity_avatar) # => /identity/avatar
432
- router.path(:new_identity_avatar) # => /identity/avatar/new
433
- router.path(:edit_identity_avatar) # => /identity/avatar/new
461
+ router.path(:identity_avatar) # => "/identity/avatar"
462
+ router.path(:new_identity_avatar) # => "/identity/avatar/new"
463
+ router.path(:edit_identity_avatar) # => "/identity/avatar/new"
434
464
 
435
- router.path(:identity_api_keys) # => /identity/api_keys
436
- router.path(:identity_api_key, id: 1) # => /identity/api_keys/:id
437
- router.path(:new_identity_api_key) # => /identity/api_keys/new
438
- router.path(:edit_identity_api_key, id: 1) # => /identity/api_keys/:id/edit
465
+ router.path(:identity_api_keys) # => "/identity/api_keys"
466
+ router.path(:identity_api_key, id: 1) # => "/identity/api_keys/:id"
467
+ router.path(:new_identity_api_key) # => "/identity/api_keys/new"
468
+ router.path(:edit_identity_api_key, id: 1) # => "/identity/api_keys/:id/edit"
439
469
  ```
440
470
 
441
471
 
@@ -443,8 +473,9 @@ router.path(:edit_identity_api_key, id: 1) # => /identity/api_keys/:id/edit
443
473
  ### RESTful Resources:
444
474
 
445
475
  ```ruby
446
- router = Hanami::Router.new
447
- router.resources 'flowers'
476
+ Hanami::Router.new do
477
+ resources "flowers"
478
+ end
448
479
  ```
449
480
 
450
481
  It will map:
@@ -510,9 +541,9 @@ It will map:
510
541
 
511
542
 
512
543
  ```ruby
513
- router.path(:flowers) # => /flowers
514
- router.path(:flower, id: 23) # => /flowers/23
515
- router.path(:edit_flower, id: 23) # => /flowers/23/edit
544
+ router.path(:flowers) # => "/flowers"
545
+ router.path(:flower, id: 23) # => "/flowers/23"
546
+ router.path(:edit_flower, id: 23) # => "/flowers/23/edit"
516
547
  ```
517
548
 
518
549
 
@@ -520,41 +551,46 @@ router.path(:edit_flower, id: 23) # => /flowers/23/edit
520
551
  If you don't need all the default endpoints, just do:
521
552
 
522
553
  ```ruby
523
- router = Hanami::Router.new
524
- router.resources 'flowers', only: [:new, :create, :show]
554
+ Hanami::Router.new do
555
+ resources "flowers", only: [:new, :create, :show]
556
+ end
525
557
 
526
558
  #### which is equivalent to:
527
559
 
528
- router.resources 'flowers', except: [:index, :edit, :update, :destroy]
560
+ Hanami::Router.new do
561
+ resources "flowers", except: [:index, :edit, :update, :destroy]
562
+ end
529
563
  ```
530
564
 
531
565
 
532
566
  If you need extra endpoints:
533
567
 
534
568
  ```ruby
535
- router = Hanami::Router.new
536
- router.resources 'flowers' do
537
- member do
538
- get 'toggle' # maps to Flowers::Toggle
539
- end
569
+ router = Hanami::Router.new do
570
+ resources "flowers" do
571
+ member do
572
+ get "toggle" # maps to Flowers::Toggle
573
+ end
540
574
 
541
- collection do
542
- get 'search' # maps to Flowers::Search
543
- end
544
- end
575
+ collection do
576
+ get "search" # maps to Flowers::Search
577
+ end
578
+ end
579
+ end
545
580
 
546
- router.path(:toggle_flower, id: 23) # => /flowers/23/toggle
547
- router.path(:search_flowers) # => /flowers/search
581
+ router.path(:toggle_flower, id: 23) # => "/flowers/23/toggle"
582
+ router.path(:search_flowers) # => "/flowers/search"
548
583
  ```
549
584
 
550
585
 
551
586
  Configure controller:
552
587
 
553
588
  ```ruby
554
- router = Hanami::Router.new
555
- router.resources 'blossoms', controller: 'flowers'
589
+ router = Hanami::Router.new do
590
+ resources "blossoms", controller: "flowers"
591
+ end
556
592
 
557
- router.path(:blossom, id: 23) # => /blossoms/23 # Will route to Flowers::Show
593
+ router.path(:blossom, id: 23) # => "/blossoms/23" # Will route to Flowers::Show
558
594
  ```
559
595
 
560
596
  #### Nested Resources
@@ -562,20 +598,21 @@ router.path(:blossom, id: 23) # => /blossoms/23 # Will route to Flowers::Show
562
598
  We can nest resource(s):
563
599
 
564
600
  ```ruby
565
- router = Hanami::Router.new
566
- router.resources :users do
567
- resource :avatar
568
- resources :favorites
569
- end
601
+ router = Hanami::Router.new do
602
+ resources :users do
603
+ resource :avatar
604
+ resources :favorites
605
+ end
606
+ end
570
607
 
571
- router.path(:user_avatar, user_id: 1) # => /users/1/avatar
572
- router.path(:new_user_avatar, user_id: 1) # => /users/1/avatar/new
573
- router.path(:edit_user_avatar, user_id: 1) # => /users/1/avatar/edit
608
+ router.path(:user_avatar, user_id: 1) # => "/users/1/avatar"
609
+ router.path(:new_user_avatar, user_id: 1) # => "/users/1/avatar/new"
610
+ router.path(:edit_user_avatar, user_id: 1) # => "/users/1/avatar/edit"
574
611
 
575
- router.path(:user_favorites, user_id: 1) # => /users/1/favorites
576
- router.path(:user_favorite, user_id: 1, id: 2) # => /users/1/favorites/2
577
- router.path(:new_user_favorites, user_id: 1) # => /users/1/favorites/new
578
- router.path(:edit_user_favorites, user_id: 1, id: 2) # => /users/1/favorites/2/edit
612
+ router.path(:user_favorites, user_id: 1) # => "/users/1/favorites"
613
+ router.path(:user_favorite, user_id: 1, id: 2) # => "/users/1/favorites/2"
614
+ router.path(:new_user_favorites, user_id: 1) # => "/users/1/favorites/new"
615
+ router.path(:edit_user_favorites, user_id: 1, id: 2) # => "/users/1/favorites/2/edit"
579
616
  ```
580
617
 
581
618
  ### Body Parsers
@@ -593,11 +630,13 @@ It comes with a built-in JSON parser and allows to pass custom parsers.
593
630
  #### JSON Parsing
594
631
 
595
632
  ```ruby
596
- require 'hanami/router'
597
- require 'hanami/middleware/body_parser'
633
+ # frozen_string_literal: true
634
+
635
+ require "hanami/router"
636
+ require "hanami/middleware/body_parser"
598
637
 
599
638
  app = Hanami::Router.new do
600
- patch '/books/:id', to: ->(env) { [200, {},[env['router.params'].inspect]] }
639
+ patch "/books/:id", to: ->(env) { [200, {}, [env["router.params"].inspect]] }
601
640
  end
602
641
 
603
642
  use Hanami::Middleware::BodyParser, :json
@@ -627,13 +666,15 @@ If you want to use a different JSON backend, include `multi_json` in your `Gemfi
627
666
  #### Custom Parsers
628
667
 
629
668
  ```ruby
630
- require 'hanami/router'
631
- require 'hanami/middleware/body_parser'
669
+ # frozen_string_literal: true
670
+
671
+ require "hanami/router"
672
+ require "hanami/middleware/body_parser"
632
673
 
633
- # See Hanami::Routing::Parsing::Parser
634
- class XmlParser < Hanami::Routing::Parsing::Parser
674
+ # See Hanami::Middleware::BodyParser::Parser
675
+ class XmlParser < Hanami::Middleware::BodyParser::Parser
635
676
  def mime_types
636
- ['application/xml', 'text/xml']
677
+ ["application/xml", "text/xml"]
637
678
  end
638
679
 
639
680
  # Parse body and return a Hash
@@ -645,7 +686,7 @@ class XmlParser < Hanami::Routing::Parsing::Parser
645
686
  end
646
687
 
647
688
  app = Hanami::Router.new do
648
- patch '/authors/:id', to: ->(env) { [200, {},[env['router.params'].inspect]] }
689
+ patch "/authors/:id", to: ->(env) { [200, {}, [env["router.params"].inspect]] }
649
690
  end
650
691
 
651
692
  use Hanami::Middleware::BodyParser, XmlParser
@@ -665,13 +706,15 @@ curl http://localhost:2300/authors/1 \
665
706
  ## Testing
666
707
 
667
708
  ```ruby
668
- require 'hanami/router'
709
+ # frozen_string_literal: true
710
+
711
+ require "hanami/router"
669
712
 
670
713
  router = Hanami::Router.new do
671
- get '/books/:id', to: 'books#show', as: :book
714
+ get "/books/:id", to: "books#show", as: :book
672
715
  end
673
716
 
674
- route = router.recognize('/books/23')
717
+ route = router.recognize("/books/23")
675
718
  route.verb # "GET"
676
719
  route.action # => "books#show"
677
720
  route.params # => {:id=>"23"}
@@ -683,7 +726,7 @@ route.action # => "books#show"
683
726
  route.params # => {:id=>"23"}
684
727
  route.routable? # => true
685
728
 
686
- route = router.recognize('/books/23', method: :post)
729
+ route = router.recognize("/books/23", method: :post)
687
730
  route.verb # "POST"
688
731
  route.routable? # => false
689
732
  ```
@@ -700,13 +743,8 @@ __Hanami::Router__ uses [Semantic Versioning 2.0.0](http://semver.org)
700
743
  4. Push to the branch (`git push origin my-new-feature`)
701
744
  5. Create new Pull Request
702
745
 
703
- ## Acknowledgements
704
-
705
- Thanks to Joshua Hull ([@joshbuddy](https://github.com/joshbuddy)) for his
706
- [http_router](http://rubygems.org/gems/http_router).
707
-
708
746
  ## Copyright
709
747
 
710
- Copyright © 2014-2017 Luca Guidi – Released under MIT License
748
+ Copyright © 2014-2019 Luca Guidi – Released under MIT License
711
749
 
712
750
  This project was formerly known as Lotus (`lotus-router`).