多个clojure-liberator决策读取请求体

时间:2015-07-12 17:02:37

标签: clojure java-io liberator slurp

我有一个defresource,它应该接受POST请求,验证请求正文:malformed-decision,将正文保存到数据库:post!-decision并返回保存的正文:handle-created。

(defn parse-project [context] (json/read-str
                               (slurp (get-in context [:request :body]))
                               :key-fn keyword))    
(defresource add-new-project
         :malformed? (fn[ctx] (not (project-is-valid (parse-project ctx))))
         :handle-malformed (fn [_] (generate-string (str "Malformed json!")))
         ...
         :post! (fn [ctx] (save-to-db (parse-project ctx))
         :handle-created  (fn [ctx] (... parse-project ...))

所以我的代码读取了三次带有slurp-function的ByteArrayInputStream(来自:request:body)。第一次工作,但第二次调用slurp时,nil作为参数传递,并出现java.io.EOFException:JSON错误。我想读者会开始阅读上一次留下的地方。

我怎么能三次阅读请求正文?或者有没有很好的方法将读取结果保存到变量并将其传递给其他解放器决策?

1 个答案:

答案 0 :(得分:3)

context可以通过每个决策和行动功能的结果进行更新。您可以在malformed?中解析一次项目并返回一个包含已解析项目的映射,该映射将合并到上下文中,以便可用于以下决策和操作。例如:

(defresource add-new-project
  :malformed? (fn[ctx] (let [project (parse-project ctx)]
                         (when (project-is-valid project)
                           {:project project})))
  :handle-malformed (fn [_] (generate-string (str "Malformed json!")))
  :post! (fn [ctx] (save-to-db (:project ctx)))
  :handle-created (fn [ctx] (do-something (:project ctx))))

如果项目有效,:malformed?将返回{:project project}地图,该地图将合并到上下文中,以用于下一个决策和操作。 如果项目无效,它将返回nil,因此在:handle-malformed中继续执行。

有关解放者执行模型的更多信息,请参阅https://clojure-liberator.github.io/liberator/doc/execution-model.html