Search code examples
phpclojurering

Accepting array style urlencoded parameters with ring


I'm replacing an old PHP API with one implemented in Clojure. The API has an endpoint that accepts array style parameters, for example:

http://localhost/create?person[name]=John&person[gender]=m

PHP would yield this:

array(
    "person" => array(
        "name" => "John",
        "gender" => "m"
    )
)

We're currently using Ring's wrap-params to process the parameters. If you look at the source for ring's input decoding, you'll see that ring takes a simple view of decoding the input parameters - just split it on the & and =. It therefore yields the following:

{"person[name]" "John"
 "person[gender]" "m"}

To be explicit, in Clojure, I'd want the following parameters:

{"person" {"name" "John"
           "gender" "m"}}

How can I set up my ring app to properly accept the array style parameters supported by PHP? Is there any third party middleware I can use?


Solution

  • If you need to support these nested parameter arrays, that functionality is provided in the ring.middleware.nested-params package. The wrap-nested-params middleware works together with wrap-params - params puts the data in the request map's :params key, and nested params replaces it with the fully expanded input.

    (use '[ring.middleware.params :only (wrap-params)])
    (use '[ring.middleware.nested-params :only (wrap-nested-params)])
    
    (def app (wrap-params (wrap-nested-params your-handler)))