机架:映射更复杂的路线

时间:2014-10-04 15:45:36

标签: ruby rack

考虑config.ru的以下小节:

run Rack::URLMap.new(                                                                                                                      
  "/" => Ramaze,                                                                                                                           
  "/apixxx" => MyGrapeAPI.new                                                                                                                            
)

这很有效。 (注意xxx后缀)。每个发送到/apixxx/*的请求都会转到Grape API端点,其他所有内容都由Ramaze应用提供。 (Ramaze建立在Rack上。)

但是,我真正想要做的是映射/api而不是/apixxx。但是,Ramaze应用程序恰好有/api/v1/*下的端点。我想要的是让/api下不在/api/v1下的每个请求都去Grape API(例如/api/somethingelse),并且每个/api/v1/*请求都要转到Ramaze。

我尝试在URLMap中使用Regexps而不是Strings,但这并不起作用。我尝试过使用URLMap和Rack :: Cascade的组合,但没有成功。

最理想的情况是,如果我可以使用Regexps进行映射,或者如果我可以使用一段代码进行映射,我就会参加比赛。

2 个答案:

答案 0 :(得分:1)

可能会使用对正则表达式执行检查的中间件,如下所示:https://stackoverflow.com/a/3070083/519736

答案 1 :(得分:0)

这是我最终使用的内容,感谢@rekado的提示。

# config.ru

class APIRoutingAdapter
  def initialize(app)
    @app = app
  end

  def call(env)
    request = Rack::Request.new(env)
    # Version 1 of the API was served from Ramaze, but the API has since been
    # moved out of Ramaze.
    if request.path =~ %r{/api/(?!v1)}
      # Have the Grape API handle the request
      env_without_api_prefix = env.dup
      ['REQUEST_PATH', 'PATH_INFO', 'REQUEST_URI'].each do |key|
        env_without_api_prefix[key] = env_without_api_prefix[key].gsub(%r{^/api}, '')
      end

      TheGrapeAPI.new.call(env_without_api_prefix)
    else
      # Let Ramaze handle the request
      @app.call(env)
    end
  end
end

use APIRoutingAdapter

run Ramaze