Как использовать лотос-роутер с Rack::Builder::map
Есть ли способ использовать карту и пространство имен роутера (lotus) вместе? Ниже образец config.ru
Я пытаюсь запустить как демо.
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
1 ответ
Решение
Ваша проблема связана с приоритетом do..end
в вызовах методов. В вашем коде раздел
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
анализируется Руби как
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
Другими словами, блок передается run
не Lotus::Router.new
как вы и хотели run
просто игнорирует блок.
Чтобы исправить это, вам нужно убедиться, что блок связан с конструктором маршрутизатора, а не с вызовом run
, Есть несколько способов сделать это. Вы могли бы использовать {...}
скорее, чем do...end
, поскольку это имеет более высокий приоритет:
run Lotus::Router.new {
#...
}
Альтернативой было бы назначить маршрутизатор локальной переменной и использовать его в качестве аргумента run
:
router = Lotus::Router.new do
#...
end
run router