2

With Compojure, is there a way to redirect to one of the defined routes, other than having to format the request URL?

For example, in the following simplified defroutes declaration:

(defroutes app-routes
  ; ...
  (GET "/something-that-may-redirect" [query-param]
    ; parse `query-param` into `arg1` and `arg2` and:
    (ring.util.response/redirect (format "/another-route?param1=%s&param2=%s" arg1 arg2))
  (GET "/another-route" [param1 param2] ...)
  ; ...

Here, I have to format the URL to redirect to (and normally also deal with escaping), in order for this URL to be later parsed by Compojure itself and extract back the values for param1 and param2.

So the question is if there is an approach to redirect and let Compojure to format the request URL, knowing that it already has information about the arguments? Something as simple as:

(redirect "/another-route" arg1 arg2)

which would format a URL itlsef into:

"/another-route?param1=[value of arg1]&param2=[value of arg2]"

P.S. The idea itself it not new certainly. Some other Web frameworks have similar features - for example, with Python's Flask web framework one can use url_for to create a well-formatted and escaped URL out of base path and query parameter values:

# for example, in Python's Flask framework
url_for('route-name', param1='value1', param2='value2')
Tim
  • 12,318
  • 7
  • 50
  • 72
  • I don't understand what you mean by "parse query-param into arg1 and arg2." You're destructuring /path?query-param=x into x, what parsing do you need? – Diego Basch Oct 21 '15 at 23:31
  • Yes, I'm not talking about parsing - the question is about formatting. – Tim Oct 22 '15 at 07:36
  • Can't you just take the whole query string and do `(str "/another-route?" query-string)`? – Diego Basch Oct 22 '15 at 17:05
  • Well, this is the point of my question - how to get the query string in the first place. I can certainly format it myself - this is one of the options; my question is - how to do it the best and the easiest. Is there something that is made specifically for that or do we need to format URL's on our own? Some other Web frameworks have similar features - for example, with Python's Flask web framework one can use `url_for` (http://flask.pocoo.org/docs/0.10/quickstart/#url-building) to create a well-formatted and escaped URL out of base path and query parameter values. – Tim Oct 22 '15 at 18:31
  • @dbasch I've updated the question above to be more clear - thanks for the question! – Tim Oct 22 '15 at 18:37
  • Getting the query string from the request is trivial, see my answer. – Diego Basch Oct 22 '15 at 18:41

2 Answers2

2

I believe this is a duplicate question How to convert map to URL query string in Clojure/Compojure/Ring?

This code would achieve the goal the poster seeks.

(defroutes app-routes
  (GET "/something-that-may-redirect" [arg1 arg2]
       (redirect (str "/another-route" "?" (ring.util.codec/form-encode {:param1 arg1 :param2 arg2}))))
  (GET "/another-route" response (str response)))
Community
  • 1
  • 1
Ricardo Acuna
  • 530
  • 2
  • 10
0

Instead of destructuring a parameter, you can use the whole request and extract the query string, then redirect to the new url with the query string appended:

  (GET "/foo" req
   (ring.util.response/redirect (str "/bar?" (:query-string req))))
Diego Basch
  • 12,764
  • 2
  • 29
  • 24
  • Oh, excuse me, I think I didn't express what I actually meant - I don't need to reuse another query string, but rather construct a completely new one, potentially with different set of query parameters. – Tim Oct 22 '15 at 21:08