在中间件阶段访问路径参数

时间:2013-07-18 23:58:00

标签: clojure routes params middleware compojure

我正在尝试编写一个中间件,用于将请求中的所有字符串对象id转换为ObjectId对象。

我使用以下方法实现此目的:

(defn get-object-id
  [id]
  (when (and (string? id) (re-matches object-id-regex id))
    (ObjectId. id)))

(defn maybe-obj->object-id [obj]
  (or (get-object-id obj) obj))

(defn- convert-string->object-ids [obj]
  (cwalk/postwalk
    (partial pcommon/maybe-obj->object-id) obj))

(defn warp-params-string->objectid
  "convert strings to object ids"
  [handler]
  (fn [request]
    (handler (update-in request [:params] convert-string->object-ids))))

这适用于为json,请求参数等而来的所有参数。但这并不适用于路径参数,例如:fst for url“/:fst”。我查看了GET宏,并且路径参数被注入该宏内部的某个地方。但是由于GET / POST等最后执行,我的中间件无权访问这些。任何实现这一目标的优雅方式。

1 个答案:

答案 0 :(得分:2)

这些/:foo/:bar - 样式参数由于URI上的模式匹配而受到约束,并且在各个路由的定义中指定了模式。外层甚至不知道图案的样子。因此,实际上不可能将这些处理提升到中间件。

相反,您可以编写一个宏,比如说with-preprocessed-params来包装路由处理程序的主体。如果它最终在许多处理程序中有用,您还可以提供自己的GET版本&安培;有限公司委托给Compojure的宏,其中包含在你的param处理宏中。

如果您希望在更多中间件层中使用此预处理的结果,那么这不是一个很好的解决方案。在这种情况下,假设您很乐意将匹配的实际URI路径段留给核心处理程序层,您可以在一个中间件中执行其他参数类型的预处理,然后使用您的GET& Co.变体只预处理路径参数。