Class: Hanami::Router
- Inherits:
-
Object
- Object
- Hanami::Router
- Defined in:
- lib/hanami/router.rb,
lib/hanami/router/leaf.rb,
lib/hanami/router/node.rb,
lib/hanami/router/trie.rb,
lib/hanami/router/block.rb,
lib/hanami/router/route.rb,
lib/hanami/router/errors.rb,
lib/hanami/router/params.rb,
lib/hanami/router/prefix.rb,
lib/hanami/router/segment.rb,
lib/hanami/router/version.rb,
lib/hanami/router/redirect.rb,
lib/hanami/router/constants.rb,
lib/hanami/router/inspector.rb,
lib/hanami/router/rack_utils.rb,
lib/hanami/router/url_helpers.rb,
lib/hanami/router/globbed_path.rb,
lib/hanami/router/mounted_path.rb,
lib/hanami/router/formatter/csv.rb,
lib/hanami/router/recognized_route.rb,
lib/hanami/router/formatter/human_friendly.rb
Overview
Rack compatible, lightweight and fast HTTP Router.
Defined Under Namespace
Modules: Formatter Classes: Block, Error, GlobbedPath, Inspector, InvalidRouteExpansionError, Leaf, MissingEndpointError, MissingRouteError, MountedPath, Node, NotRoutableEndpointError, Params, Prefix, RecognizedRoute, Redirect, Route, Segment, Trie, UnknownHTTPStatusCodeError, UrlHelpers
Constant Summary collapse
- VERSION =
Returns the hanami-router version.
"3.0.0.rc1"- ROUTER_PARSED_BODY =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"router.parsed_body"
Instance Attribute Summary collapse
-
#inspector ⇒ Hanami::Router::Inspector
readonly
Routes inspector.
-
#url_helpers ⇒ Object
readonly
private
URL helpers for other Hanami integrations.
Class Method Summary collapse
-
.define(&blk) ⇒ Proc
Returns the given block as it is.
- .rack_3? ⇒ Boolean private
Instance Method Summary collapse
-
#call(env) ⇒ Array
Resolve the given Rack env to a registered endpoint and invokes it.
-
#delete(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts DELETE requests for the given path.
- #fixed(env) ⇒ Object private
-
#get(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts GET requests for the given path.
- #globbed_or_mounted(env) ⇒ Object private
-
#initialize(base_url: DEFAULT_BASE_URL, prefix: DEFAULT_PREFIX, resolver: DEFAULT_RESOLVER, not_allowed: NOT_ALLOWED, not_found: NOT_FOUND, block_context: nil, inspector: nil, &blk) ⇒ Hanami::Router
constructor
Initialize the router.
-
#link(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts LINK requests for the given path.
-
#mount(app, at:, **constraints) ⇒ Object
Mount a Rack application at the specified path.
- #not_allowed(env) ⇒ Object private
- #not_found(env) ⇒ Object private
-
#options(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts OPTIONS requests for the given path.
-
#patch(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts PATCH requests for the given path.
-
#path(name, variables = {}) ⇒ String
Generate an relative URL for a specified named route.
-
#post(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts POST requests for the given path.
-
#put(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts PUT requests for the given path.
-
#recognize(env, params = {}, options = {}) ⇒ Hanami::Routing::RecognizedRoute
Recognize the given env, path, or name and return a route for testing inspection.
-
#redirect(path, code:, to: nil, as: nil) ⇒ Object
Defines a route that redirects the incoming request to another path.
-
#redirect_permanent(path, to: nil, as: nil) ⇒ Object
Defines a route that permanently redirects the incoming request to another path.
-
#redirect_temporary(path, to: nil, as: nil) ⇒ Object
Defines a route that temporarily redirects the incoming request to another path.
-
#root(to: nil, &blk) ⇒ Object
Defines a named root route (a GET route for “/”).
-
#scope(path, as: nil, &blk) ⇒ Object
Defines a routing scope.
-
#trace(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts TRACE requests for the given path.
-
#unlink(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts UNLINK requests for the given path.
-
#url(name, variables = {}) ⇒ URI::HTTP, URI::HTTPS
Generate an absolute URL for a specified named route.
- #variable(env) ⇒ Object private
Constructor Details
#initialize(base_url: DEFAULT_BASE_URL, prefix: DEFAULT_PREFIX, resolver: DEFAULT_RESOLVER, not_allowed: NOT_ALLOWED, not_found: NOT_FOUND, block_context: nil, inspector: nil, &blk) ⇒ Hanami::Router
Initialize the router
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/hanami/router.rb', line 78 def initialize(base_url: DEFAULT_BASE_URL, prefix: DEFAULT_PREFIX, resolver: DEFAULT_RESOLVER, not_allowed: NOT_ALLOWED, not_found: NOT_FOUND, block_context: nil, inspector: nil, &blk) # rubocop:disable Layout/LineLength # TODO: verify if Prefix can handle both name and path prefix @path_prefix = Prefix.new(prefix) @name_prefix = Prefix.new("") @url_helpers = UrlHelpers.new(base_url) @base_url = base_url @resolver = resolver @not_allowed = not_allowed @not_found = not_found @block_context = block_context @fixed = {} @variable = {} @globs_and_mounts = [] @blk = blk @inspector = inspector instance_eval(&blk) if blk end |
Instance Attribute Details
#inspector ⇒ Hanami::Router::Inspector (readonly)
Routes inspector
38 39 40 |
# File 'lib/hanami/router.rb', line 38 def inspector @inspector end |
#url_helpers ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
URL helpers for other Hanami integrations
31 32 33 |
# File 'lib/hanami/router.rb', line 31 def url_helpers @url_helpers end |
Class Method Details
.define(&blk) ⇒ Proc
Returns the given block as it is.
53 54 55 |
# File 'lib/hanami/router.rb', line 53 def self.define(&blk) blk end |
.rack_3? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
7 8 9 |
# File 'lib/hanami/router/rack_utils.rb', line 7 def self.rack_3? defined?(Rack::Headers) end |
Instance Method Details
#call(env) ⇒ Array
Resolve the given Rack env to a registered endpoint and invokes it.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/hanami/router.rb', line 103 def call(env) endpoint, params = lookup(env) unless endpoint return not_allowed(env) || not_found(env) end # Rack 3 no longer requires "rack.input" to be rewindable. Force input to be rewindable to # maintain Rack 2 behavior while we're still supporting both. if (input = env[::Rack::RACK_INPUT]) && !input.respond_to?(:rewind) env[::Rack::RACK_INPUT] = Rack::RewindableInput.new(input) end endpoint.call( _params(env, params) ).to_a end |
#delete(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts DELETE requests for the given path.
301 302 303 |
# File 'lib/hanami/router.rb', line 301 def delete(path, to: nil, as: nil, **constraints, &blk) add_route(::Rack::DELETE, path, to, as, constraints, &blk) end |
#fixed(env) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
692 693 694 695 696 697 698 699 |
# File 'lib/hanami/router.rb', line 692 def fixed(env) path_info = env[::Rack::PATH_INFO] # Treat empty PATH_INFO as "/" for route matching. This allows root routes (defined as "/") to # match the empty PATH_INFO that is set for requests to a mount without a trailing slash. path_info = DEFAULT_PREFIX if path_info == EMPTY_STRING @fixed.dig(env[::Rack::REQUEST_METHOD], path_info) end |
#get(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts GET requests for the given path. It also defines a route to accept HEAD requests.
224 225 226 227 |
# File 'lib/hanami/router.rb', line 224 def get(path, to: nil, as: nil, **constraints, &blk) add_route(::Rack::GET, path, to, as, constraints, &blk) add_route(::Rack::HEAD, path, to, as, constraints, &blk) end |
#globbed_or_mounted(env) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
709 710 711 712 713 714 715 716 |
# File 'lib/hanami/router.rb', line 709 def globbed_or_mounted(env) @globs_and_mounts.each do |path| result = path.endpoint_and_params(env) return result unless result.empty? end nil end |
#link(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts LINK requests for the given path.
358 359 360 |
# File 'lib/hanami/router.rb', line 358 def link(path, to: nil, as: nil, **constraints, &blk) add_route(::Rack::LINK, path, to, as, constraints, &blk) end |
#mount(app, at:, **constraints) ⇒ Object
Mount a Rack application at the specified path. All the requests starting with the specified path, will be forwarded to the given application.
All the other methods (eg ‘#get`) support callable objects, but they restrict the range of the acceptable HTTP verb. Mounting an application with #mount doesn’t apply this kind of restriction at the router level, but let the application to decide.
503 504 505 506 507 508 509 510 511 |
# File 'lib/hanami/router.rb', line 503 def mount(app, at:, **constraints) path = prefixed_path(at) prefix = Segment.fabricate(path, **constraints) @globs_and_mounts << MountedPath.new(prefix, @resolver.call(path, app)) if inspect? @inspector.add_route(Route.new(http_method: "*", path: at, to: app, constraints: constraints)) end end |
#not_allowed(env) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
720 721 722 723 724 725 |
# File 'lib/hanami/router.rb', line 720 def not_allowed(env) allowed_http_methods = _not_allowed_fixed(env) || _not_allowed_variable(env) return if allowed_http_methods.nil? @not_allowed.call(env, allowed_http_methods) end |
#not_found(env) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
729 730 731 |
# File 'lib/hanami/router.rb', line 729 def not_found(env) @not_found.call(env) end |
#options(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts OPTIONS requests for the given path.
339 340 341 |
# File 'lib/hanami/router.rb', line 339 def (path, to: nil, as: nil, **constraints, &blk) add_route(::Rack::OPTIONS, path, to, as, constraints, &blk) end |
#patch(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts PATCH requests for the given path.
263 264 265 |
# File 'lib/hanami/router.rb', line 263 def patch(path, to: nil, as: nil, **constraints, &blk) add_route(::Rack::PATCH, path, to, as, constraints, &blk) end |
#path(name, variables = {}) ⇒ String
Generate an relative URL for a specified named route. The additional arguments will be used to compose the relative URL - in
case it has tokens to match - and for compose the query string.
539 540 541 |
# File 'lib/hanami/router.rb', line 539 def path(name, variables = {}) url_helpers.path(name, variables) end |
#post(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts POST requests for the given path.
244 245 246 |
# File 'lib/hanami/router.rb', line 244 def post(path, to: nil, as: nil, **constraints, &blk) add_route(::Rack::POST, path, to, as, constraints, &blk) end |
#put(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts PUT requests for the given path.
282 283 284 |
# File 'lib/hanami/router.rb', line 282 def put(path, to: nil, as: nil, **constraints, &blk) add_route(::Rack::PUT, path, to, as, constraints, &blk) end |
#recognize(env, params = {}, options = {}) ⇒ Hanami::Routing::RecognizedRoute
Recognize the given env, path, or name and return a route for testing inspection.
If the route cannot be recognized, it still returns an object for testing inspection.
681 682 683 684 685 686 687 688 |
# File 'lib/hanami/router.rb', line 681 def recognize(env, params = {}, = {}) require "hanami/router/recognized_route" env = env_for(env, params, ) endpoint, params = lookup(env) RecognizedRoute.new(endpoint, _params(env, params)) end |
#redirect(path, code:, to: nil, as: nil) ⇒ Object
Defines a route that redirects the incoming request to another path.
‘code:` is required. For the common cases, prefer #permanent_redirect (301) or #temporary_redirect (302). Use this method when you need a less common redirect code such as 303 See Other, 307 Temporary Redirect, or 308 Permanent Redirect.
399 400 401 |
# File 'lib/hanami/router.rb', line 399 def redirect(path, code:, to: nil, as: nil) get(path, to: _redirect(to, code), as: as) end |
#redirect_permanent(path, to: nil, as: nil) ⇒ Object
Defines a route that permanently redirects the incoming request to another path.
Issues a 301 Moved Permanently response, indicating that the resource has moved to a new location and all future requests should use the new URL.
NOTE: Browsers cache permanent redirects aggressively. Once a client has followed a 301, it may not re-request the original URL, making the redirect hard to undo without clearing the browser cache. Prefer #redirect_temporary when in doubt.
423 424 425 |
# File 'lib/hanami/router.rb', line 423 def redirect_permanent(path, to: nil, as: nil) get(path, to: _redirect(to, PERMANENT_REDIRECT_CODE), as: as) end |
#redirect_temporary(path, to: nil, as: nil) ⇒ Object
Defines a route that temporarily redirects the incoming request to another path.
Issues a 302 Found response, indicating that the resource is temporarily available at a different URL and future requests should continue to use the original URL.
443 444 445 |
# File 'lib/hanami/router.rb', line 443 def redirect_temporary(path, to: nil, as: nil) get(path, to: _redirect(to, TEMPORARY_REDIRECT_CODE), as: as) end |
#root(to: nil, &blk) ⇒ Object
Defines a named root route (a GET route for “/”)
159 160 161 |
# File 'lib/hanami/router.rb', line 159 def root(to: nil, &blk) get(ROOT_PATH, to: to, as: :root, &blk) end |
#scope(path, as: nil, &blk) ⇒ Object
Defines a routing scope. Routes defined in the context of a scope, inherit the given path as path prefix and as a named routes prefix.
468 469 470 471 472 473 474 475 476 477 478 479 480 |
# File 'lib/hanami/router.rb', line 468 def scope(path, as: nil, &blk) path_prefix = @path_prefix name_prefix = @name_prefix begin @path_prefix = @path_prefix.join(path.to_s) @name_prefix = @name_prefix.join((as || path).to_s) instance_eval(&blk) ensure @path_prefix = path_prefix @name_prefix = name_prefix end end |
#trace(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts TRACE requests for the given path.
320 321 322 |
# File 'lib/hanami/router.rb', line 320 def trace(path, to: nil, as: nil, **constraints, &blk) add_route(::Rack::TRACE, path, to, as, constraints, &blk) end |
#unlink(path, to: nil, as: nil, **constraints, &blk) ⇒ Object
Defines a route that accepts UNLINK requests for the given path.
377 378 379 |
# File 'lib/hanami/router.rb', line 377 def unlink(path, to: nil, as: nil, **constraints, &blk) add_route(::Rack::UNLINK, path, to, as, constraints, &blk) end |
#url(name, variables = {}) ⇒ URI::HTTP, URI::HTTPS
Generate an absolute URL for a specified named route. The additional arguments will be used to compose the relative URL - in
case it has tokens to match - and for compose the query string.
569 570 571 |
# File 'lib/hanami/router.rb', line 569 def url(name, variables = {}) url_helpers.url(name, variables) end |
#variable(env) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
703 704 705 |
# File 'lib/hanami/router.rb', line 703 def variable(env) @variable[env[::Rack::REQUEST_METHOD]]&.find(env[::Rack::PATH_INFO]) end |