我正在尝试编写一个中间件,用于将请求中的所有字符串对象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等最后执行,我的中间件无权访问这些。任何实现这一目标的优雅方式。
答案 0 :(得分:2)
这些/:foo/:bar
- 样式参数由于URI上的模式匹配而受到约束,并且在各个路由的定义中指定了模式。外层甚至不知道图案的样子。因此,实际上不可能将这些处理提升到中间件。
相反,您可以编写一个宏,比如说with-preprocessed-params
来包装路由处理程序的主体。如果它最终在许多处理程序中有用,您还可以提供自己的GET
版本&安培;有限公司委托给Compojure的宏,其中包含在你的param处理宏中。
如果您希望在更多中间件层中使用此预处理的结果,那么这不是一个很好的解决方案。在这种情况下,假设您很乐意将匹配的实际URI路径段留给核心处理程序层,您可以在一个中间件中执行其他参数类型的预处理,然后使用您的GET
& Co.变体只预处理路径参数。