8

org.clojure/clojure-contrib "1.2.0" ring "1.1.8" compojure "1.1.5" clout "1.1.0"

(defroutes rest-routes
    (GET "/" [] "<p> Hello </p>")
    (POST "/api/v1/:stor/sync" [stor] (start-sync stor))
    (POST ["/api/v1/:stor/:txn/data/:file" :file #".*"] [stor txn file] (txn-add stor txn file))
    (ANY "*" [] "<p>Page not found. </p>"))

In the second POST, I also want to pass all http-headers to "txn-add" handler. I did lot of google and look through the code, but couldn't find anything useful.

I know, I can use the following to pass headers (but then it doesn't parse url request),

(POST "/api/v1"
  {headers :headers} (txn-add "dummy stor" "dummy txn" headers))

Also, how do I pass the content (i.e. :body) of POST request to "txn-add" ?

2 Answers2

11

If the second argument to GET, POST etc is not a vector, it's a destructuring binding form for request. That means you can do things like:

(GET "/my/path"
   {:keys [headers params body] :as request} 
   (my-fn headers body request))

To pick out the parts of request you want. See the Ring SPEC and Clojure's docs on binding & destructuring

Joost Diepenmaat
  • 17,633
  • 3
  • 44
  • 53
  • I'm somewhat new to clojure as a whole (just been two weeks into this). Therefore, not sure if I understood your answer. However, I need to parse "url" portion for [stor txn file] and then need to pass :headers as well in `(POST ["/api/v1/:stor/:txn/data/:file" :file #".*"] [stor txn file] (txn-add stor txn file))`. So, I need combination of vector argument and destructuring binding form, how to achieve that – Shanti Adhikari May 23 '13 at 06:41
6

The whole request map can be specified in the bindings using :as keyword in bindings and then used to read headers or body :

(POST ["/api/v1/:stor/:txn/data/:file" :file #".*"] 
      [stor txn file :as req] 
      (my-handler stor txn file req))
Ankur
  • 33,367
  • 2
  • 46
  • 72
  • thanks. It did the magic (however it is still a black magic to me, as I couldn't figure this out by staring through compojure code on github). Now, I'm able to pass all the parameters (url compnonents and headers) to the handler. – Shanti Adhikari May 23 '13 at 06:50
  • Check out https://github.com/weavejester/compojure/blob/master/src/compojure/core.clj#L66 for how the bindings are handled – Ankur May 23 '13 at 06:59
  • Thanks Ankur. Looking at implementation of 'vector-bindings', things are now clear to me as how it all works. – Shanti Adhikari May 23 '13 at 07:11