compojure wrap-json-body无法正常工作

时间:2014-03-16 11:29:38

标签: clojure compojure ring

我正在使用下面的代码尝试访问PUT请求中的一些json输入但是我返回的内容有:body {},我不确定我做错了什么?

(ns compliant-rest.handler
  (:use compojure.core ring.middleware.json)
  (:require [compojure.handler :as handler]
            [compojure.route :as route]
            [ring.util.response :refer [response]]
            [clojure.data.json :refer [json-str]]))

(defroutes app-routes
  (PUT "/searches" {body :params} (response body))
  (route/resources "/")
  (route/not-found "Not Found"))

(def app
  (-> (handler/site app-routes)
      (wrap-json-body)
      (wrap-json-response)))

(app {
      :request-method :put 
      :uri "/searches" 
      :content-type "application/json" 
      :body (with-in-str (json-str {:field "value"}))
      })

;; {:status 200, :headers {"Content-Type" "application/json; charset=utf-8"}, :body "{}"}

另外,我是Clojure / Lisp的新手,任何关于我的语法和风格的评论都会受到赞赏。

2 个答案:

答案 0 :(得分:4)

有两件事突出:

未解析的请求体不应该是字符串,而应该是InputStream。这意味着您的测试表达式不会按原样运行。

wrap-json-body用clojure数据结构替换(:body请求)。它没有放入任何内容(:params request)或(:body(:params request))。你想要wrap-json-params。

答案 1 :(得分:3)

感谢Joost和评论,我发现有一个响铃函数ring.util.io.string-input-stream可以做我错误认为with-in-str做的事情。最后我做了以下工作:

(ns compliant-rest.handler
  (:use compojure.core ring.middleware.json)
  (:require [compojure.handler :as handler]
            [compojure.route :as route]
            [ring.util.response :refer [response]]
            [ring.util.io :refer [string-input-stream]]
            [clojure.data.json :refer [json-str]]))

(defroutes app-routes
  (PUT "/searches/:id" {params :params body :body}
       (response body))
  (route/resources "/")
  (route/not-found "Not Found"))

(def app
  (-> (handler/site app-routes)
      (wrap-json-body)
      (wrap-json-response)))

;; Example request
(app {
      :request-method :put 
      :uri "/searches/1" 
      :content-type "application/json" 
      :body (string-input-stream (json-str {:key1 "val1"}))
      })
;; {:status 200, :headers {"Content-Type" "application/json; charset=utf-8"}, :body "{\"key1\":\"val1\"}"}

非常棒,我可以创建一个简单的地图并调用我的api的入口点,而无需任何服务器或模拟。我完全被Clojure,repl和light table拉进了整个动态语言中!