How do I make fun of a json post request in a ring?

I use peridot - https://github.com/xeqi/peridot to test my application for a call, and its performance, until I try to make fun of a mail request with json data:

 (require '[cheshire.core: as json])
 (use 'compojure.core)

 (defn json-post [req]
   (if (: body req)
     (json / parse-string (slurp (: body req)))))

 (defroutes all-routes
   (POST "/ test / json" req (json-response (json-post req))))

 (def app (compojure.handler / site all-routes))

 (use 'peridot.core)

 (-> (session app)
     (request "/ test / json"
              : request-method: post
              : body (java.io.ByteArrayInputStream. (.getBytes "hello" "UTF-8")))

gives an IOException: stream closed .

Is there a better way to do this?

+8
clojure ring
source share
2 answers

TL; DR:

 (-> (session app) (request "/test/json" :request-method :post :content-type "application/json" :body (.getBytes "\"hello\"" "UTF-8"))) 

When peridot creates a request map, the default will be application/x-www-form-urlencoded for the content type for the request :post . In the application specified by wrap-params (which is included by compojure.handler/site ), it will try to read :body to parse any parameters given in the urlencoded form. Then json-post again tries to read :body . However, an InputStream intended to be read once, and this throws an exception.

There are basically two ways to solve the problem:

  • Delete compojure.handler/site .
  • Add content type to request (as done in TL; DR)
+9
source share
 (require '[cheshire.core :as json]) (-> (session app) (request "/test/json" :request-method :post :content-type "application/json" :body (json/generate-string data)) 

No need to call .getBytes , just pass json with the :body parameter.

+4
source share

All Articles