gpt4 book ai didi

clojure - 为什么Ring中间件的顺序需要颠倒?

转载 作者:行者123 更新时间:2023-12-03 14:30:03 25 4
gpt4 key购买 nike

我正在为Ring编写一些中间件,而对于为什么我必须颠倒中间件的顺序我感到非常困惑。

我找到了这个blog post,但没有解释为什么我必须将其反转。

这是博客文章的简短摘录:

(def app
(wrap-keyword-params (wrap-params my-handler)))


响应将是:

{; Trimmed for brevity
:params {"my_param" "54"}}


请注意,还没有调用wrap关键字params,因为params哈希还不存在。但是,当您像这样反转中间件的顺序时:

(def app
(wrap-params (wrap-keyword-params my-handler)))

{; Trimmed for brevity
:params {:my_param "54"}}


有用。

有人可以解释一下为什么您必须逆转中间件的顺序吗?

最佳答案

它有助于可视化实际上是什么中间件。

(defn middleware [handler]
(fn [request]
;; ...
;; Do something to the request before sending it down the chain.
;; ...
(let [response (handler request)]
;; ...
;; Do something to the response that's coming back up the chain.
;; ...
response)))


那个权利对我来说几乎是个“哈哈”时刻。

乍一看,令人困惑的是中间件没有应用于请求,这正是您所考虑的。

回想一下,Ring app只是一个接受请求并返回响应的函数(这意味着它是一个处理程序):

((fn [request] {:status 200, ...}) request)  ;=> response


让我们缩小一点。我们得到另一个处理程序:

((GET "/" [] "Hello") request)  ;=> response


让我们再放大一点。我们找到 my-routes处理程序:

(my-routes request)  ;=> response


好吧,如果您想在将请求发送到 my-routes处理程序之前做点什么?您可以使用其他处理程序包装它。

((fn [req] (println "Request came in!") (my-routes req)) request)  ;=> response


有点难以理解,所以让我们为清楚起见。我们可以定义一个返回该处理程序的函数。中间件是采用处理程序并将其包装到另一个处理程序的函数。它不返回响应。它返回一个可以返回响应的处理程序。

(defn println-middleware [wrapped-func]
(fn [req]
(println "Request came in!")
(wrapped-func req)))

((println-middleware my-route) request) ;=> response


如果我们甚至需要在 println-middleware收到请求之前做点什么,那么我们可以再次包装它:

((outer-middleware (println-middleware my-routes)) request)  ;=> response


关键在于,与您的 my-routes一样, my-handler是实际上将请求作为参数的唯一命名函数。

最后的示范:

(handler3 (handler2 (handler1 request)))  ;=> response
((middleware1 (middleware2 (middleware3 handler1))) request) ;=> response


我写很多东西是因为我可以同情。但是,请滚动回到我的第一个 middleware示例,希望它更有意义。

关于clojure - 为什么Ring中间件的顺序需要颠倒?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19455801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com