在Rails中,中间件可以在每个请求后执行吗?



我不需要这个功能,只是出于好奇。

我知道中间件在每个请求之前运行。

然而,期望中间件在每个请求之后运行是合理的吗?如果是这样的话,我们该怎么做呢?

如果没有,日志中间件如何报告对请求的响应?

在Rails中,中间件被安排在一个堆栈中(你可以认为这个堆栈是一个管道),请求和响应将堆栈扔向两个相反的方向。

rails中间件栈

$ rails middleware
request  # ...                                ^
|      use Rack::ETag                       | 
|      use Rack::TempfileReaper             |
|      use Warden::Manager                  | 
|      run Bookstore::Application.routes   response 
V

为了将堆栈中的中间件链接在一起,较高的中间件将递归地调用较低的中间件,让我们看一些代码来理解它是如何工作的,假设我们有两个中间件m1和m2,其中m1在堆栈中被安排在m2的正上方,然后流请求和响应将抛出m1, m2如下(步骤顺序为[1],[2],…):

class M1
def initialize(app)
@app = app
end
def call(env) # [1] higher middleware call
# [2] before call recursive
# you could get request
request = ActionDispatch::Request.new env
# log request , or something else ...

status, headers, body =  # [9] get response from M2
@app.call(env) # [3] call recursive M2

# log response, or do something else ...
[status, headers, body] # [10] return response to higher middleware
end  
end
class M2
def initialize(app)
@app = app
end
def call(env) # [4] M1 call
# [5] before call recursive lower middleware
# same as above 
status, headers, body =  # [7] get response from lower middlewares
@app.call(env) # [6] call recursive lower middleware

# log response, or do something else ...
[status, headers, body] # [8] return response to M1 above
end 
end

最低的中间件是Rails app,所以调用栈看起来像一个链

call( ... call( ... call( ... rails_app.call() ))..)

所以你可以改变应用程序的行为(或你的应用程序如何处理请求/响应)通过添加/inserting_before(after)/删除节点在这个链,非常灵活!!

最新更新