让我们假设,我已经获得了一个端点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))
效果很好但body
是InputStream
,所以我只能阅读一次。
有没有办法在不止一个使用原子的钩子中使用请求的body
?
我想到了解决方案:
body
的字符串版本添加到ctx
参数中。malformed?
的结果传递给post!
... 谢谢!
答案 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))