hanami-router 1.3.2 → 2.0.0.alpha1

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.
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`).