JSON body

114 views
Skip to first unread message

André Thieme

unread,
Sep 30, 2009, 10:21:48 AM9/30/09
to Compojure
I get POST requests with the header content-type application/json.
In the request object now the value of :body is something like
#<Input org.mortbay.jetty.HttpParser$Input@118cb72>
What is the idiomatic way to get the clear text of the json request?

I would like to read the json body in several with-xyz handlers.
Currently i .read repeatedly from (:body request) and take elements
out of this while they are not -1, map them to chars and apply str to
that. This gives me the clear text body, but it seems a bit
complicated, no?
And the problem:
I would like to read the body from several with-xyz handlers. But this
can't be done, because the first use of .read consumes the body, and I
can't read it again. Any suggestions?
(Unfortunately the search function does not work)

André Thieme

unread,
Sep 30, 2009, 10:43:36 AM9/30/09
to Compojure
Okay, I discovered that one can do
(slurp* (:body request)) to get the json body.
But this can only be done once.
I would like to make a handler that will do
this initially and then assoc the clear text to
the request object, before it is used anywhere else.
Is there a way to update the request object?

André Thieme

unread,
Sep 30, 2009, 11:28:19 AM9/30/09
to Compojure
I found some examples for middleware, and how they call
(handler (assoc request :my-key :my-value))
I suppose the call of handler forwards the request to
the next handler?

James Reeves

unread,
Sep 30, 2009, 2:19:30 PM9/30/09
to Compojure
Yep, basically you want something like this:

(use 'clojure.contrib.json.read)
(use 'clojure.contrib.duck-streams)

(defn json-request? [request]
(= (get-in request [:headers "content-type"])
"application/json"))

(defn assoc-json [request]
(if (json-request? request)
(assoc request :json (read-json (slurp* (request :body))))
request))

(defn with-json [handler]
(fn [request]
(handler (assoc-json request))))

And then just decorate your handlers with the with-json middleware:

(defroutes your-routes
(POST "/test"
(str "You posted: " (pr-str (request :json))))
(ANY "*"
[404 "Resource not found"]))

(decorate your-routes
with-json)

- James

Daniel Renfer

unread,
Sep 30, 2009, 3:24:24 PM9/30/09
to comp...@googlegroups.com

I can see this potentially being useful. Would you mind including
these in compojure?

Reply all
Reply to author
Forward
0 new messages