Search code examples
clojurecompojurering

Compojure - map query parameters with string keys


I know I can map the query string as a keyworkd map.

(defroutes my-routes
  (GET "/" {params :query-params} params))

But is there a way do the same with a string keyed map? (Using Compojure or Ring)

The point here is not to iterate over the map or use a function, but create it with string keys by default.

{ :a "b" } -> {"a" "b"}

Solution

  • Compojure 1.5.1 does not parse any query strings by default (by not using any middleware). However, this might have been different in earlier versions.

    (require '[compojure.core :refer :all])
    (require '[clojure.pprint :refer [pprint]])
    
    (defroutes handler
      (GET "/" x
           (with-out-str (pprint x)))) ;; just a way to receive a pretty printed string response
    
    $ curl localhost:3000/?a=b
    {:ssl-client-cert nil,
     :protocol "HTTP/1.1",
     :remote-addr "127.0.0.1",
     :params {},  ;; EMPTY!
     :route-params {},
     :headers
     {"user-agent" "curl/7.47.1", "accept" "*/*", "host" "localhost:3000"},
     :server-port 3000,
     :content-length nil,
     :compojure/route [:get "/"],
     :content-type nil,
     :character-encoding nil,
     :uri "/",
     :server-name "localhost",
     :query-string "a=b",  ;; UNPARSED QUERY STRING
     :body
     #object[org.eclipse.jetty.server.HttpInputOverHTTP 0x6756d3a3 "HttpInputOverHTTP@6756d3a3"],
     :scheme :http,
     :request-method :get}
    

    Ring offers the ring.params.wrap-params middleware, which parses the query string and creates a hashmap of it under the params-key:

    (defroutes handler
      (wrap-params (GET "/" x
                     (prn-str (:params x)))))
    
    $ curl localhost:3000/?a=55
    {"a" "55"}
    

    Additionaly ring.params.wrap-params can be used:

    (defroutes handler
      (wrap-params (wrap-keyword-params (GET "/" x
                                         (prn-str (:params x))))))
    
    $ curl localhost:3000/?a=55
    {:a "55"}