Search code examples
clojure

How to parse URL parameters in Clojure?


If I have the request "size=3&mean=1&sd=3&type=pdf&distr=normal" what's the idiomatic way of writing the function (defn request->map [request] ...) that takes this request and returns a map {:size 3, :mean 1, :sd 3, :type pdf, :distr normal}

Here is my attempt (using clojure.walk and clojure.string):

(defn request-to-map
   [request]
   (keywordize-keys
      (apply hash-map
             (split request #"(&|=)"))))

I am interested in how others would solve this problem.


Solution

  • You can do this easily with a number of Java libraries. I'd be hesitant to try to roll my own parser unless I read the URI specs carefully and made sure I wasn't missing any edge cases (e.g. params appearing in the query twice with different values). This uses jetty-util:

    (import '[org.eclipse.jetty.util UrlEncoded MultiMap])
    
    (defn parse-query-string [query]
      (let [params (MultiMap.)]
        (UrlEncoded/decodeTo query params "UTF-8")
        (into {} params)))
    
    user> (parse-query-string "size=3&mean=1&sd=3&type=pdf&distr=normal")
    {"sd" "3", "mean" "1", "distr" "normal", "type" "pdf", "size" "3"}