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"- 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.
Rack env key containing the request body as parsed by the body parser middleware. Signals that the body has already been parsed, so the router should not attempt to parse it again.
"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 |
# 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(_env_with_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.
299 300 301 |
# File 'lib/hanami/router.rb', line 299 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.
690 691 692 693 694 695 696 697 |
# File 'lib/hanami/router.rb', line 690 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.
222 223 224 225 |
# File 'lib/hanami/router.rb', line 222 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.
707 708 709 710 711 712 713 714 |
# File 'lib/hanami/router.rb', line 707 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.
356 357 358 |
# File 'lib/hanami/router.rb', line 356 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.
501 502 503 504 505 506 507 508 509 |
# File 'lib/hanami/router.rb', line 501 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.
718 719 720 721 722 723 |
# File 'lib/hanami/router.rb', line 718 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.
727 728 729 |
# File 'lib/hanami/router.rb', line 727 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.
337 338 339 |
# File 'lib/hanami/router.rb', line 337 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.
261 262 263 |
# File 'lib/hanami/router.rb', line 261 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.
537 538 539 |
# File 'lib/hanami/router.rb', line 537 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.
242 243 244 |
# File 'lib/hanami/router.rb', line 242 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.
280 281 282 |
# File 'lib/hanami/router.rb', line 280 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.
679 680 681 682 683 684 685 686 |
# File 'lib/hanami/router.rb', line 679 def recognize(env, params = {}, = {}) require "hanami/router/recognized_route" env = env_for(env, params, ) endpoint, params = lookup(env) RecognizedRoute.new(endpoint, _env_with_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.
397 398 399 |
# File 'lib/hanami/router.rb', line 397 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.
421 422 423 |
# File 'lib/hanami/router.rb', line 421 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.
441 442 443 |
# File 'lib/hanami/router.rb', line 441 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 "/")
157 158 159 |
# File 'lib/hanami/router.rb', line 157 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.
466 467 468 469 470 471 472 473 474 475 476 477 478 |
# File 'lib/hanami/router.rb', line 466 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.
318 319 320 |
# File 'lib/hanami/router.rb', line 318 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.
375 376 377 |
# File 'lib/hanami/router.rb', line 375 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.
567 568 569 |
# File 'lib/hanami/router.rb', line 567 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.
701 702 703 |
# File 'lib/hanami/router.rb', line 701 def variable(env) @variable[env[::Rack::REQUEST_METHOD]]&.find(env[::Rack::PATH_INFO]) end |