【问题标题】:How to inject a Rack middleware into an existing Rack app?如何将 Rack 中间件注入现有的 Rack 应用程序?
【发布时间】:2015-04-15 12:28:38
【问题描述】:

给定一个不是 Rails 的 Rack 应用,

builder.rb:

def app
  Rack::Builder.new{
    use Rack::Static, urls:static_paths, root:'public'

    run ThaApp
  }.to_app
end

如何使用 spec_helper 注入测试中间件?

【问题讨论】:

    标签: ruby rack middleware rack-middleware


    【解决方案1】:

    如果您使用的是 Builder(使用、运行等),它确实看起来您可以在运行时轻松地注入或删除中间件。这是代码:https://github.com/rack/rack/blob/master/lib/rack/builder.rb

    请注意,它构建了中间件堆栈,当您调用 run 时,它会在中间件对象树中实例化堆栈(称为“@use”),每个中间件对象都引用下一个对象 - 请参阅方法“use”和“to_app”。

    所以:不要认为 Builder 旨在允许在堆栈中动态添加和减去中间件。

    您可以重新构建一个新的动态堆栈,或者使用多个 Rack 应用程序,无论是否测试中间件,或者像 Rails 那样做一些后空翻来动态重新配置堆栈。

    您还可以仅在测试模式下添加测试中间件,或者可以轻松停用的中间件,使其成为传递中间件。然后您的 spec_helper 将设置并清除告诉它通过的变量。

    【讨论】:

    • 好的,谢谢。我想既然你可以在 Rails 中做到这一点,那么在 Rack 中也可以做到。我目前正在为测试使用单独的 Rack 构建,但这会产生重复。我认为这比用测试代码污染生产版本要好。
    • 用于测试的独立机架构建器可能与您在这里得到的一样干净。
    • Rails 保留不同的非 Builder 堆栈。如果你需要它来做其他事情,那就太好了。但是,如果您需要为这个问题构建/复制它,那么结果将是太多的代码和复杂性。
    • 构建后不能更改中间件有什么特殊原因吗?我的意思是,如果中间件存储在@use,你可以更新@use吗?还是有更多的事情发生?
    • 更多内容。每个中间件都是在使用之前构建的,并引用到该构造函数的最近(向内)邻居。您需要从@use 堆栈重新制作中间件堆栈。如果您确定可以这样做,那很好,但是对旧堆栈的任何引用都会出现错误的行为。通常你只打一次“运行”电话,这会破坏你对@use的更改。
    【解决方案2】:

    由于我想预先添加到中间件堆栈,解决这个特殊用例很容易。

    给定一个名为“app”的应用,添加新的中间件:use ...

    def new_app
      Rack::Builder.new do
        use ...
        use ...
    
        run app
      end.to_app
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-15
      • 1970-01-01
      • 1970-01-01
      • 2011-10-31
      相关资源
      最近更新 更多