Clojure 如何拦截Compojure请求并基于测试执行它?
我有一些路线Clojure 如何拦截Compojure请求并基于测试执行它?,clojure,compojure,ring,Clojure,Compojure,Ring,我有一些路线 (defroutes some-routes (GET "one" [] one) (GET "two" [] two)) (defroutes other-routes (GET "three" [] three) (GET "four" [] four)) (defroutes more-routes (GET "five" [] five) (GET "six" [] six)) (def all-routes (routes a
(defroutes some-routes
(GET "one" [] one)
(GET "two" [] two))
(defroutes other-routes
(GET "three" [] three)
(GET "four" [] four))
(defroutes more-routes
(GET "five" [] five)
(GET "six" [] six))
(def all-routes
(routes app-routes
(-> some-routes session/wrap-session my-interceptor)
(-> more-routes session/wrap-session my-other-interceptor)
other-routes))
我想截取一些路由
,但不截取其他路由
,并根据请求执行测试(检查会话中是否存在密钥和其他内容)。我有不止一个我的另一个拦截器
做同样的事情,但不同
所以我从这个开始:
(defn my-interceptor [handler]
(fn [request]
(prn (-> request :session :thing-key))
(let [thing (-> request :session :thing-key-id)]
(if (nil? thing)
(-> (response "Not authenticated"))
(handler request)))))
如果会话中设置了:thing key
,这将允许访问处理程序
不幸的是,这并不能很好地处理多组路由。此检查应仅适用于某些路线
,而不适用于其他路线
。但在执行处理程序之前,我们不知道路由是否匹配。此时处理程序已经执行了。我可以将其重写为执行handler
,然后仅在响应为非nil时执行检查,但这意味着我在检查auth之前已经执行了处理程序
我接着说,这说明了问题:
(defn add-app-version-header [handler]
(fn [request]
(let [resp (handler request)
headers (:headers resp)]
(assoc resp :headers
(assoc headers "X-APP-INFO" "MyTerifficApp Version 0.0.1-Alpha")))))
我该怎么做?我想要的是:
- 在处理请求之前检查响应(和其他逻辑)的一种方法
- 我可以应用于一大组routes的处理程序
- 这不会应用于应用程序中的所有路线
- 我将让不止一个这样的处理程序对会话执行不同类型的检查
我应该怎么做呢?拥有单独的处理程序或中间件的方法是使用
compojure.core/routes
分解路由,并仅在需要的地方使用处理程序
在你的情况下,如果你把你的其他路线
放在第一位,你的问题应该得到解决
例如:
(def app-routes
(compojure.core/routes
other-routes
(-> some-routes
session/wrap-session
my-interceptor)))
记住compojure路由,您总是可以编写一个自定义的defroutes
,仅当路由与请求匹配时才调用处理程序,这是
这样,如果您有多个条件处理程序,则不需要依赖于将这些路由放在合成的末尾
请注意,这种方法是在您希望保持路由处理代码干净的情况下使用的
如果你不想使用自己的defroutes
,只需调用内部拦截器:
(defroutes routes
(GET "/" request (interceptor request show-all))
(defn interceptor
[request handler]
谢谢不过我有不止一种支票,所以我认为你的建议不适用,把非支票项目放在第一位?我会考虑你的第二个建议。老实说,我是新来的(对Clojure来说也是很新的)。我是否必须放弃我的
defroutes
并重新编写路由才能这样做?还有一些功能,例如,如果route是def-
'ed,则。这是否意味着从compojure中复制粘贴代码块,或者我是否遗漏了要点?嗯,您可以随时在route handler中调用处理程序,而不是在外部调用处理程序,将更新答案以显示。谢谢,最后一点现在解决了我的问题,在我学习compojure和ring的其他部分时,这足以让某些东西发挥作用。
(my-def-routes routes
(GET "/" request (show-all request))
(defroutes routes
(GET "/" request (interceptor request show-all))
(defn interceptor
[request handler]