我试图编写一个宏,以便仅在特定环境中有条件地将compojure处理程序包装在中间件中我似乎在评估顺序中迷失了方向,我应该引用什么/如何引用我目前的尝试如下:

(defn empty-middleware [handler]
  (fn [request] (handler request)))

(defmacro prod [handler middleware]
  (if (= "production" (System/getenv "APP_ENV"))
    (middleware handler)
    (empty-middleware handler)))

预期用途是:
(in/prod (fn [handler]  (airbrake/wrap-airbrake handler config/airbrake-api-key)))

---编辑---
更多信息:
in/prod应该在线程宏中使用,该宏在许多中间软件中包装路由,如:
(-> handler
    middleware1
    middleware2
    (in/prod (middleware3 middleware-3-param1))

middleware3和in/prod都需要处理程序作为参数在括号中包装middleware3的计算结果不可能将处理程序作为参数传递因此我认为需要一个宏我研究了如何使in/prod成为一个函数,将middleware3和middleware params作为参数传递:
(defn prod [handler middleware & middleware-params]
  (if (= "production" (System/getenv "APP_ENV"))
    (apply middleware handler middleware-params)
    handler))

但是它稍微改变了语法电话看起来像:
(-> handler
    middleware1
    middleware2
    (in/prod middleware3 middleware-3-param1)

我将如何使用以下语法:
(in/prod (middleware3 middleware-3-param1)

最佳答案

如果您希望应用的中间件也是一个宏,因此您正遭受着宏传染的折磨,那么您可能需要将它作为宏在这种情况下,您只需要返回两个可能的s表达式之一的宏包含在结果代码中一个是直接调用处理程序,另一个是封装在给定的中间件中。

(defmacro prod [handler middleware]
  (if (= "production" (System/getenv "APP_ENV"))
    `(~middleware ~handler) ;; or (list middleware handler)
     handler))

如果您当前没有受到宏传染的影响,但无法通过在其他地方删除宏来修复,则不需要使用此类宏,示例中的代码可以简单地用作函数而不是宏在这两种情况下都不需要空的middlware位。

09-13 11:20