Clojure ring middleware to handle url array

370 views Asked by At

The ClojureScript cljs-ajax client library converts {:b [1 2]} to b[0]=1&b[1]=2

For example:

(http/get "http://example.com" {:b [1 2]})

results in a request to:

"http://example.com?b[0]=1&b[1]=2"

How can I setup my ring middleware to handle this format on the server side? I would like to convert it back to the original structure:

{:b [1 2]}

I am using the middleware below, but it does not work properly:

(ring.middleware.keyword-params/wrap-keyword-params)
(ring.middleware.params/wrap-params :encoding encoding)
(ring.middleware.nested-params/wrap-nested-params)
2

There are 2 answers

0
Mamun On

There is no issue in middleware side. The issue is in cljs-ajax's ajax.core/params-to-str api. It is generating duplicate URL for different data format.

(ajax.core/params-to-str {:b [1 3]})
;; => "b[0]=1&b[1]=3"

(ajax.core/params-to-str {:b {0 1 1 3}})
;; => "b[0]=1&b[1]=3"

For array, format should be b[]=1&b[]=3.

0
Tim X On

I would suggest the middleware is working fine, but perhaps there is a misalignment between what it does and your expectations. I'm assuming that what you have above is just a list of the middleware and not how you are calling/using it. If not, your way off track.

Strictly speaking, what you are trying to pass is not a nested parameter. What you really have are parameters with names like "b[0]" and "b[1]", which each have a value. This is because you are using get rather than post and cljs-ajax needs to translate your clojure data structure to normal query parameter format. Unless there is a strong reason to do this, you will find life much easier if you use a post method rather than get and embed the data in the body as json/edn/transit whatever. It also has the added benefit that your data won't be sent 'public' as part of the URL and captured by logs all over the place.

A useful server side package to use with cljs-ajax and post commands is ring.middleware.format. This will simplify the parsing of the data in the body of your request and supports multiple different data encoding methods.