Clojure compojure包装json正文不工作

Clojure compojure包装json正文不工作,clojure,compojure,ring,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

我正在使用下面的代码尝试访问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新手,如果您对我的语法和风格有任何评论,我将不胜感激。

有两件事非常突出:

未解析的请求主体不应该是字符串,而是InputStream。这意味着您的测试表达式无法按原样工作

wrap json body用clojure数据结构替换(:body请求)。它不会在(:params请求)或(:body(:params请求))中放入任何内容。您需要包装json参数。

有两件事很突出:

未解析的请求主体不应该是字符串,而是InputStream。这意味着您的测试表达式无法按原样工作


wrap json body用clojure数据结构替换(:body请求)。它不会在(:params请求)或(:body(:params请求))中放入任何内容。你需要包装json参数。

多亏了Joost和我发现的注释,有一个ring函数
ring.util.io.string输入流
,它实现了我在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的动态语言所吸引

感谢Joost和我发现的注释,有一个ring函数
ring.util.io.string输入流
,它完成了我在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的动态语言所吸引

with in str
是从字符串创建输入流。那么我该如何分解结构以从路由访问body数据结构呢?with in str创建一个输入流,但它将其绑定到*
中的
*in。这可能有效,但我建议您使用ring.mock.request库中的
request
body
函数。您可以使用
(PUT)/搜索“{body:body}…”
从请求中仅获取:body值。
使用in str
从字符串创建输入流。那么我该如何分解结构以从路由访问body数据结构呢?with in str创建一个输入流,但它将其绑定到*
中的
*in。这可能有效,但我建议您在ring.mock.request库中使用
请求
body
函数。您可以使用
(PUT)/搜索“{body:body}…”
从请求中仅获取:body值。