Is there a way to use map and the (lotus)router namespacing together? Below is a sample config.ru
I'm trying to get running as a demo.
require 'bundler'
Bundler.require
module Demo
class Application
def initialize
@app = Rack::Builder.new do
map '/this_works' do
run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["this_works"]]}
end
map '/api' do
run Lotus::Router.new do
get '/api/', to: ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
get '/*', to: ->(env) { [200, {}, ["This is catch all: #{ env['router.params'].inspect }!"]] }
end
end
end
end
def call(env)
@app.call(env)
end
end
end
run Demo::Application.new
Your problem is due to the precedence of do..end
in method calls. In your code the section
run Lotus::Router.new do
get '/api/', to: ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
get '/*', to: ->(env) { [200, {}, ["This is catch all: #{ env['router.params'].inspect }!"]] }
end
is parsed by Ruby as
run(Lotus::Router.new) do
get '/api/', to: ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
get '/*', to: ->(env) { [200, {}, ["This is catch all: #{ env['router.params'].inspect }!"]] }
end
In other words the block is passed to run
, not to Lotus::Router.new
as you intended, and run
simply ignores the block.
To fix it you need to ensure the block is associated with the constructor of the router rather than the call to run
. There are a couple of ways to do this. You could use {...}
rather than do...end
, as that has a higher precedence:
run Lotus::Router.new {
#...
}
An alternative would be to assign the router to a local variable, and use that as the argument to run
:
router = Lotus::Router.new do
#...
end
run router
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With