看起来需要第二个映射:
map('/people') { run Api::People }
map('/people.json') { run Api::People }
当我添加它时,/people.json 会按照我的意愿发送到 Api::People 的根路径。
这种方法的问题是我有很多嵌套资源,并转化为很多重复映射。
我已经确定了一个既优雅又符合逻辑的设计。你知道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/businesses/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
另一个好处是所有路由都是完整的,因此您不必经常记住“/”实际映射到什么。