Clojure compojure 中间件和箭头语法

3

我正在尝试理解compojure中间件:

以下代码来自compojure模板

(def app
  (wrap-defaults app-routes site-defaults))

这是否等同于以下内容?
(def app
  (-> app-routes
      (wrap-defaults api-defaults)))

我不确定这一点,因为在以下代码中,my-middleware2my-middleware1 之前被调用。

(def app
  (-> api-routes
      (wrap-defaults api-defaults)
      (my-middleware1)
      (my-middleware2)))

1
Compojure在Ring的基础上提供了一些方便的宏。准确地说,中间件是Ring的,而不是Compojure的。 - myguidingstar
1个回答

3

你是正确的:

(def app
  (wrap-defaults app-routes site-defaults))

相当于:

(def app
  (-> app-routes
      (wrap-defaults api-defaults)))

箭头被称为线程优先宏,可以让您以线性方式编写嵌套的s表达式。
在第二个示例中,当HTTP请求到来时,调用my-middleware2my-middleware1更有意义。您正在创建一个Ring处理程序,而不是直接调用中间件。
(def app
  (-> api-routes
    (wrap-defaults api-defaults)
    my-middleware1
    my-middleware2))

展开为:

被扩展为:

(def app
  (my-middleware2 (my-middleware1 (wrap-defaults app-routes api-defaults))))

当HTTP请求到来时,my-middleware2首先处理它,对其进行操作(例如提取会话数据),然后将其传递给下一个中间件,直到其中一个返回HTTP响应。
注意:我从(my-middleware1)(my-middleware2)中删除了括号。这样使用时意味着my-middleware1是一个函数,当不带参数调用时,返回一个中间件函数。这可能是您想要的,但并不是常见做法。

谢谢,这很有帮助。这里使用一个线程持续宏是否合理?这里的普遍做法是什么?例如,在添加JSON解析器时,应该放在哪里? - nha
1
Thread last 宏通常不与 Ring 中间件一起使用,因为惯例是 (middleware handler options) - sbensu
1
对于 JSON,请查看 https://github.com/ring-clojure/ring-json 中的 (wrap-json-body handler),并在任何其他假定请求主体为 Clojure 数据结构的处理程序之前添加它。 - sbensu
1
这个回答解决了我很多有关中间件和线程优先的问题,非常感谢大家!=) - sova

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接