在Rails中,中间件可以在每次请求后执行吗?
In Rails, can middleware execute after each request?
我不需要这个功能,只是出于好奇才问的。
我知道中间件 运行 在每个请求之前。
但是,期望中间件在每次请求后 运行 合理吗?
如果是这样的话,我们该怎么做呢?
如果不是,记录器中间件如何报告对请求的响应?
在Rails中,中间件被安排在一个堆栈中(你可以认为这个堆栈是一个管道),请求和响应从两个相反的方向抛出堆栈。
rails 中间件栈
$ rails middleware
request # ... ^
| use Rack::ETag |
| use Rack::TempfileReaper |
| use Warden::Manager |
| run Bookstore::Application.routes response
V
为了把堆栈中的那些中间件link放在一起,高层中间件会递归调用底层中间件,让我们看一些代码来理解它是如何工作的,假设我们有2个中间件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
最底层的中间件是Railsapp,所以调用栈看起来像一个链
call( ... call( ... call( ... rails_app.call() ))..)
因此您可以通过 adding/inserting_before(之后)/删除此链中的节点来更改应用程序行为(或您的应用程序如何处理 request/response),非常灵活!!!
我不需要这个功能,只是出于好奇才问的。
我知道中间件 运行 在每个请求之前。
但是,期望中间件在每次请求后 运行 合理吗?
如果是这样的话,我们该怎么做呢?
如果不是,记录器中间件如何报告对请求的响应?
在Rails中,中间件被安排在一个堆栈中(你可以认为这个堆栈是一个管道),请求和响应从两个相反的方向抛出堆栈。
rails 中间件栈
$ rails middleware
request # ... ^
| use Rack::ETag |
| use Rack::TempfileReaper |
| use Warden::Manager |
| run Bookstore::Application.routes response
V
为了把堆栈中的那些中间件link放在一起,高层中间件会递归调用底层中间件,让我们看一些代码来理解它是如何工作的,假设我们有2个中间件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
最底层的中间件是Railsapp,所以调用栈看起来像一个链
call( ... call( ... call( ... rails_app.call() ))..)
因此您可以通过 adding/inserting_before(之后)/删除此链中的节点来更改应用程序行为(或您的应用程序如何处理 request/response),非常灵活!!!