如何 运行 一个仅包含中间件的简单 Ruby Rack 应用程序?
How to run a simple Ruby Rack app that consists of only middleware?
我有一个简单的 Ruby Rack 应用程序,它只包含中间件。我真的不需要 "app",因为中间件可以完成我想要的一切。如何将我的 config.ru
定义为 运行 只有中间件作为应用程序?
require "some_middleware"
use SomeMiddleware
run -> {|env| [200, {"Content-Type" => "text/plain"}, ["I don't need this part!"]] }
Rack 应用程序(包括中间件)基本上只是一个响应 call
的对象,接受描述请求的散列并返回描述响应的数组。
当使用 rackup
文件时,Rack 使用 Rack::Builder
. The run
method just sets the “base” app:
中描述的 DSL
def run(app)
@run = app
end
use
方法存储您要包含在您的应用程序中的中间件 classes,然后在构建最终应用程序时对每个中间件执行类似的操作(与它们的顺序相反)出现在 config.ru
文件中):
@run = MiddleWare.new(@run, other_args)
比这个稍微复杂一点,但这是大体思路。中间件 class 的新实例已创建,现有应用程序作为构造函数的第一个参数传递,生成的对象成为新应用程序。这是 Rack 中间件的(没有很好记录的)“接口”:它的初始化程序的第一个参数是它正在包装的应用程序,其余的是传递给 use
.
的任何其他参数
DSL 期望总是有 run
或 map
语句,如果两者都省略,将会出现错误。
如果您的中间件是以这样一种方式编写的,它可以处理没有参数传递给它的初始化程序,并且它的行为就像一个完整的应用程序,那么您可以直接将它用作 [=19] 中的应用程序=]:
run SomeMiddleware.new
这就是 Sinatra 所做的,以允许它 used as middleware. It stores the app in the initializer if it is given, and then when a request arrives that doesn’t match any route it uses the presence of @app
to decide whether to behave as middleware 并传递请求,或者作为最终应用程序并将其视为未找到的错误。
如果您的中间件没有这种灵活性,那么您将需要提供一个应用程序来包装它,就像您在示例中所做的那样。在这种情况下,如果中间件无法正确处理请求并尝试将其传递给包装的应用程序,则让应用程序进行错误处理也可能很有用。
如果您想避免在 config.ru
中使用单独的 use
和 run
语句,您可以只使用 run
,并将一个简单的应用程序直接传递给您的中间件:
run SomeMiddleware.new(->(e){
[500, {'Content-type' => 'text/plain'}, ["Error: SomeMiddleware didn't handle request"]]
}
注意这是如何遵循上述中间件接口的:初始化程序的第一个参数是要包装的应用程序。
我有一个简单的 Ruby Rack 应用程序,它只包含中间件。我真的不需要 "app",因为中间件可以完成我想要的一切。如何将我的 config.ru
定义为 运行 只有中间件作为应用程序?
require "some_middleware"
use SomeMiddleware
run -> {|env| [200, {"Content-Type" => "text/plain"}, ["I don't need this part!"]] }
Rack 应用程序(包括中间件)基本上只是一个响应 call
的对象,接受描述请求的散列并返回描述响应的数组。
当使用 rackup
文件时,Rack 使用 Rack::Builder
. The run
method just sets the “base” app:
def run(app)
@run = app
end
use
方法存储您要包含在您的应用程序中的中间件 classes,然后在构建最终应用程序时对每个中间件执行类似的操作(与它们的顺序相反)出现在 config.ru
文件中):
@run = MiddleWare.new(@run, other_args)
比这个稍微复杂一点,但这是大体思路。中间件 class 的新实例已创建,现有应用程序作为构造函数的第一个参数传递,生成的对象成为新应用程序。这是 Rack 中间件的(没有很好记录的)“接口”:它的初始化程序的第一个参数是它正在包装的应用程序,其余的是传递给 use
.
DSL 期望总是有 run
或 map
语句,如果两者都省略,将会出现错误。
如果您的中间件是以这样一种方式编写的,它可以处理没有参数传递给它的初始化程序,并且它的行为就像一个完整的应用程序,那么您可以直接将它用作 [=19] 中的应用程序=]:
run SomeMiddleware.new
这就是 Sinatra 所做的,以允许它 used as middleware. It stores the app in the initializer if it is given, and then when a request arrives that doesn’t match any route it uses the presence of @app
to decide whether to behave as middleware 并传递请求,或者作为最终应用程序并将其视为未找到的错误。
如果您的中间件没有这种灵活性,那么您将需要提供一个应用程序来包装它,就像您在示例中所做的那样。在这种情况下,如果中间件无法正确处理请求并尝试将其传递给包装的应用程序,则让应用程序进行错误处理也可能很有用。
如果您想避免在 config.ru
中使用单独的 use
和 run
语句,您可以只使用 run
,并将一个简单的应用程序直接传递给您的中间件:
run SomeMiddleware.new(->(e){
[500, {'Content-type' => 'text/plain'}, ["Error: SomeMiddleware didn't handle request"]]
}
注意这是如何遵循上述中间件接口的:初始化程序的第一个参数是要包装的应用程序。