0

假设,我有一个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)})))

所以我的意图是:

  • 获取bodyfrom 请求,检查它是否有效 ( 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在多个不使用原子的钩子中使用请求?

我想到的解决方案:

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

谢谢!

4

1 回答 1

2

好的,这很容易,当然有一个包装器可以做到这一点......

[ring-json-params "0.1.3"]

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

(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))
于 2015-04-30T04:15:55.660 回答