Tiago Dall'Oca
Tiago Dall'Oca

Reputation: 349

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"}

Upvotes: 0

Views: 933

Answers (2)

Anton Harald
Anton Harald

Reputation: 5934

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"}

Upvotes: 1

Alan Thompson
Alan Thompson

Reputation: 29958

Not sure about compojure, but you can undo it yourself:

(use 'clojure.walk)

(stringify-keys {:a 1 :b {:c {:d 2}}}) 
;=> {"a" 1, "b" {"c" {"d" 2}}}

https://clojuredocs.org/clojure.walk/stringify-keys

Upvotes: 0

Related Questions