Reputation: 599
I'm trying to pull a value out of the url query string however I can return what I believe is a map, however when i use the below code, it doesn't process it as expected. Can anyone advise how I access specific values in the returned querystring datastructure?
http://localhost:8080/remservice?foo=bar
(defroutes my-routes
(GET "/" [] (layout (home-view)))
(GET "/remservice*" {params :query-params} (str (:parameter params))))
Upvotes: 13
Views: 7800
Reputation: 436
With compojure 1.6.1
HTTP-request-destructuring works for me in a such way:
[ring/ring-defaults "0.3.2"]
in :dependencies
in project.clj
(because compojure.handler
namespace was deprecated since 1.2 in favor of the [ring-defaults]
)[ring.middleware.defaults :refer :all]
in :require
in your.routes.namespace
(def site (wrap-defaults app site-defaults))
in your.routes.namespace
, where app
is declared via (defroutes app ...
:ring {:handler your.routes.namespace/site}
in project.clj
Upvotes: 0
Reputation: 593
In the default app for compojure 1.2.0, the querystring middleware seems included by default. You can inspect the request as such.
(GET "/" request (str request))
It should have a lot of stuff, including the params
key.
{ . . . :params {:key1 "value1" :key2 "value2} . . . }
As such, you can include a standard Clojure destructuring form to access the query parameters in your response.
(GET "/" {params :params} (str params))
Your page should then look like the following.
{"key1" "value1", "key2" "value2"}
As noted in the comment by Michal above, however, the keys are converted to strings and if you'd like to access them you need to use the get function rather than the more convenient symbol lookups.
(GET "/" {params :params} (get params "key1"))
;;the response body should be "value1"
Upvotes: 1
Reputation: 10781
I had luck in compojure 1.1.5 not needing a wrapper and being able to use the :as
directive
(GET "/tweet/:folder/:detail" [folder detail :as req]
(twitter-controller/tweet folder detail (-> req :params :oauth_verifier))
Upvotes: -1
Reputation: 84341
You'll need to wrap your handler in compojure.handler/api
or compojure.handler/site
to add appropriate middleware to gain access to :query-params
. This used to happen automagically in defroutes
, but no longer does. Once you do that, the {params :query-params}
destructuring form will cause params
to be bound to {"foo" "bar"}
when you hit /remservice
with foo=bar
as the query string.
(Or you could add in wrap-params
etc. by hand -- these reside in various ring.middleware.*
namespaces; see the code of compojure.handler
(link to the relevant file in Compojure 1.0.1) for their names.)
E.g.
(defroutes my-routes
(GET "/remservice*" {params :query-params}
(str params)))
(def handler (-> my-routes compojure.handler/api))
; now pass #'handler to run-jetty (if that's what you're using)
If you now hit http://localhost:8080/remservice?foo=bar
, you should see {"foo" "bar"}
-- the textual representation of your query string parsed into a Clojure map.
Upvotes: 21