Clojure Liberator:获取请求正文两次

时间:2015-04-30 03:06:22

标签: clojure liberator

让我们假设,我已经获得了一个端点POST /endpoint,它将JSON作为输入数据:

POST /endpoint
{
  "resource": {
    "name": "great"
  }
}

现在,我想检查传入的JSON是否有效。我认为:malformed?钩子是这样做的好地方。

所以我提出了这样的代码:

(ANY "/endpoint" [] 
     (resource
      :allowed-methods [:post]
      :available-media-types ["application/json"]
      :malformed? (fn [ctx] (let [body (get-body-from-request ctx)
                                   is-malformed (not (is-body-valid body))]
                                is-malformed)
      :post! (fn [ctx] (let [body (get-body-from-request ctx)]
                          (create-an-object body)))
      :handle-created (fn [ctx] {:method :post :body (:body @request)})))

所以我的意图是:

  • 从请求中获取body,检查它是否有效(is-body-valid
  • post!挂钩中
  • ,再次使用body并进行实际工作(create-an-object

这里的问题是get-body-from-request函数:

(defn get-body-from-request [ctx]
  (json/read-str (slurp (get-in ctx [:request :body])) :key-fn keyword))

效果很好但bodyInputStream,所以我只能阅读一次。

有没有办法在不止一个使用原子的钩子中使用请求的body

我想到了解决方案:

  1. 中间件包装器,将body的字符串版本添加到ctx参数中。
  2. malformed?的结果传递给post! ...
  3. 使用原子。
  4. 谢谢!

1 个答案:

答案 0 :(得分:2)

好的,这很简单,当然还有一个包装器可以做到这一点......

[ring-json-params "0.1.3"]

然后你只需包装你的app处理程序:

(ns my.app
  (:require [ring.middleware.json :refer [wrap-json-params]]))

(def app
  (-> handler
      (wrap-json-params)))

在您的ctx对象中,您有json-params个对象:

:malformed? (fn [ctx] (let [params (get-in ctx [:request :json-params])]
                        false))