2

我正在尝试编写一个中间件,用于将请求中的所有字符串对象 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 等最后执行,我的中间件无权访问这些。任何优雅的方式来实现这一点。

4

1 回答 1

2

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

相反,您可以编写一个宏,例如with-preprocessed-params,将您的路由处理程序的主体包装在其中。如果它最终在许多处理程序中有用,您还可以提供自己的GET& Co. 版本,委托给 Compojure 的宏,并将主体包裹在你的参数处理宏。

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

于 2013-07-19T07:27:25.753 回答