class Router
Dispatches HTTP requests to handlers using exact path and method matches.
Request targets are parsed with Protocol::URL::Reference. Handlers receive
the original request and the decoded query parameters.
Nested Classes and Modules
Definitions
def initialize
Initialize a router.
Signature
-
yields
{|router| ...} The router to configure.
Implementation
def initialize
@routes = {}
yield self if block_given?
end
def route(path, methods: nil, &handler)
Add a route.
When methods is omitted, the handler accepts every HTTP method. Otherwise,
it may be a single method or an array of methods.
Signature
-
parameter
pathString The absolute path to match.
-
parameter
methodsString | Symbol | Array(String | Symbol) | Nil The accepted HTTP methods.
-
yields
{|request, parameters| ...} The route handler.
-
parameter
requestProtocol::HTTP::Request The original request.
-
parameter
parametersHash The decoded query parameters.
-
parameter
-
returns
Router The router.
Implementation
def route(path, methods: nil, &handler)
raise ArgumentError, "A route handler is required!" unless handler
path = route_path(path)
methods = route_methods(methods)
handlers = (@routes[path] ||= {})
methods.each do |method|
if handlers.key?(method)
raise ArgumentError, "Route already defined for #{method || "any method"} #{path}!"
end
handlers[method] = handler
end
return self
end
def call(request)
Dispatch a request to a matching route.
Signature
-
parameter
requestProtocol::HTTP::Request The request to dispatch.
-
returns
Protocol::HTTP::Response | Nil The handler or error response, or
nilwhen no path matches.
Implementation
def call(request)
reference = parse_reference(request.path)
return Protocol::HTTP::Response[400] unless reference
unless handlers = @routes[reference.path]
return nil
end
unless handler = handlers[request.method] || handlers[ANY_METHOD]
allowed_methods = handlers.keys.compact.sort.join(", ")
return Protocol::HTTP::Response[405, [["allow", allowed_methods]]]
end
parameters = parse_query(reference)
return Protocol::HTTP::Response[400] unless parameters
return handler.call(request, parameters)
end