ring-clojure / ring-json

Ring middleware for handling JSON
313 stars 47 forks source link

wrap-json-body breaks if used multiple times #31

Closed tgetgood closed 10 years ago

tgetgood commented 10 years ago

I came across the following oddity a few days ago: if you create two sets of routes, wrap them both individually with wrap-json-body and them combine them, the first set work fine, but the second get nil as the request body.

E.g. (using compojure)

(defroutes router-1
  (POST "/test1" req (println (:body req))))

(defroutes router-2
  (POST "/test2" req (println (:body req))))  

(defroutes combined-router
  (-> 
    router-1
    wrap-json-body)
  (-> 
    router-2
    wrap-json-body))

POSTing json data to /test1 causes the body to be printed to the terminal, whereas posting the exact same to /test2 just prints nil.

I made a repo to test this at https://github.com/tgetgood/json-ring-test

weavejester commented 10 years ago

This is expected behaviour. Ring stores the request body in an InputStream, which means that middleware that consumes the stream, such as wrap-json-body, is side-effectful.

The reason for this is that request bodies can be very large, and it's not feasible to read them into memory by default.

This may need a note in the README, however, for those developers less familiar with Ring.

tgetgood commented 10 years ago

I see. Well if it can't be avoided that's that; it's trivial to work around anyway. A note in the docs would be nice.

Thanks for the quick response.