Compojure Ring中间件如何在中间件之外使用价值

时间:2018-08-08 01:47:38

标签: clojure middleware compojure ring

我使用compojure / swagger进行了简单的路由和中间件设置,并利用了环形中间件。

(POST "/worlds" [request]
      :body-params [name :- String]
      :header-params [token :- String]
      :middleware [wrap-api-auth]
      :summary "Creates a new world with 'name'"
      (ok (do-something-with-user)

(defn wrap-api-auth [handler]
  (fn [request]
    (let
      [token (get (:headers request) "token")
       user (db/get-user-by-token token)]
      (if user
        (handler request)     ; pass to wrapped handler
        (unauthorized {:error "unauthorized"})))))

这定义了带有一些基本身份验证的简单路由。标头参数中传递的令牌用于进行数据库查询,该查询要么返回用户并继续,要么返回false并失败。

我要完成的工作是将返回的用户回退,以便以后使用。我没有任何运气,因为我真的不知道在哪里尝试将其添加到以后可以访问的地方。我尝试使用assoc request进行访问,但似乎以后无法访问。理想的情况是我可以将其传递给do-something-with-user函数。

1 个答案:

答案 0 :(得分:3)

使用assoc向请求中添加一些数据应该可以正常工作。

您可以在https://gist.github.com/ska2342/4567b02531ff611db6a1208ebd4316e6#file-gh-validation-clj-L124找到一个示例,该示例的代码与我生产的代码非常接近。

本质上,该中间件调用

(handler (assoc request
                :validation {:valid true
                             :validation valid?}))

因此,对于您的情况,以下方法应该可以工作:

(handler (assoc request
                :user user))

如果我正确理解,您使用的解构语法来自compojure-api。根据{{​​3}}上的示例,我想说通过:middleware键设置的中间件的行为与预期的一样,您应该能够从:user中提取request最终到达您的路线。

因此,只需将request传递给do-something-with-user函数:

(POST "/worlds" request
      :body-params [name :- String]
      :header-params [token :- String]
      :middleware [wrap-api-auth]
      :summary "Creates a new world with 'name'"
      (ok (do-something-with-user request))

它应该包含您:user在中间件函数中加入的assoc。请注意request周围缺少的括号,如该答案的注释中所述。