是否可以在Sinatra中编写带有文件扩展名的根路由?

时间:2011-08-03 22:08:47

标签: ruby routing sinatra

我正在使用Sinatra编写JSON API,并使用Sinatra::Base命令将不同的资源分成map个类:

map('/people') { run Api::People }

Api::People内,/people将被映射为根路径/。我希望通过/people.json处理Api::People - 这可能吗?我无法弄清楚如何写路线。

2 个答案:

答案 0 :(得分:0)

看起来需要第二个映射:

map('/people')      { run Api::People }
map('/people.json') { run Api::People }

当我添加时,/people.json会根据需要发送到Api::People的根路径。


这种方法的问题在于我有很多嵌套资源,转换为重复映射的 lot

我已经确定了既优雅又符合逻辑的设计。您是否知道Sinatra::Base类可以将其他Sinatra::Base类作为中间件安装在其中?

一旦我弄明白,解决方案显而易见:

<强> config.ru

Dir['api/**/*.rb'].each {|file| require file }

run API::Router

<强> API / router.rb

module API
  class Router < Sinatra::Base
    use Businesses
    use People
    use Users

    get '*' do
      not_found
    end
  end
end

<强> API / businesses.rb

class API::Businesses < Sinatra::Base
  use Locations

  get '/businesses.json' do ... end
  get '/businesses/:id.json' do ... end
end

<强> API /商家/ locations.rb

class API::Businesses < Sinatra::Base
  class Locations < Sinatra::Base
    before { @business = Business.find_by_id( params[:business_id] ) }
    get '/businesses/:business_id/locations.json' do ... end
    get '/businesses/:business_id/locations/:id.json' do ... end
  end
end

另一个好处是所有路线都是完整的,因此您不必经常记住实际映射到的'/'。

答案 1 :(得分:0)

如果您想要DRYer替代品:

%w(people people.json).each do |route|
  map('/' + route) { run Api::People }
end

或者您可以在数组中包含斜杠,如%w(/path/to/api /path/to/api.json)