Adding access to the raw request body [incl. Patch]

154 views
Skip to first unread message

Moritz Angermann

unread,
Jul 19, 2009, 4:26:00 PM7/19/09
to Compojure
Hi everyone,

this is my first day with Clojure and my first attempt to use
Compojure :)
I wanted to write some RESTful service with Compojure and ended up
sending JSON straight to Compojure. The problem is, as it has been
with
Werkzeug (Python WSGI Framework), that the framework did not expose
the raw request. In this case I just wanted to parse the body as a
JSON
string.

Here's my humble attempt to add a :raw key to the request map that
holds
the raw request body.

http://github.com/angerman/compojure/commit/a97fc8fd160dde3e7edd36e65e14f13cbdc9b6de

kindest regards,
Moritz Angermann

James Reeves

unread,
Jul 19, 2009, 5:48:57 PM7/19/09
to Compojure
On Jul 19, 9:26 pm, Moritz Angermann <moritz.angerm...@gmail.com>
wrote:
> I wanted to write some RESTful service with Compojure and ended up
> sending JSON straight to Compojure. The problem is, as it has been
> with Werkzeug (Python WSGI Framework), that the framework did not
> expose the raw request.

Actually, it does :)

You can access the raw body of the request with (request :body). This
will return an InputStream instance that can then be read from. Here's
an example:

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

(defroutes site
(POST "/raw"
(prn (slurp* (request :body))))
(POST "/json"
(prn (read-json (slurp* (request :body))))))

Note that if the content-type of the request is set to "application/x-
www-form-urlencoded", then these routes will fail, because Compojure
will first try to parse the JSON as a urlencoded form, and 'use up'
the InputStream. I mention this because a lot of HTTP client libraries
assume you're sending a urlencoded form when you're doing a POST.
You'd need to explicitly set the content-type to "application/json"
for it to work.

Alternatively, you could use the routes* function:

(def site
(routes*
(POST "/raw"
(prn (slurp* (request :body))))
(POST "/json"
(prn (read-json (slurp* (request :body)))))))

This function will not add the middleware used to parse urlencoded
forms, so it'll ignore the content-type and won't touch the body's
InputStream. However, it's probably a better idea to just get the
content-type correct :)

- James

Moritz Angermann

unread,
Jul 20, 2009, 1:16:34 AM7/20/09
to comp...@googlegroups.com
Ohh nice... Thanks for the great answer! Sorry for the noise...

Kindest regards,
Moritz
On 19.07.2009, at 23:48, James Reeves <weave...@googlemail.com>
wrote:
Reply all
Reply to author
Forward
0 new messages