Fork me on GitHub
#reitit
<
2023-11-04
>
DrLjótsson08:11:59

I would like to have namespaced keywords path arguments, which requires the bracket syntax. But bracket syntax doesn't use the colon, which I find hard to visually parse. I.e., "/some/{user/id}/path" is harder for me to read than "/some/{:user/id}/path". Of note, "/some/{:user/id}/path" will not work, as the argument is parsed as the illegal keyword ::user/id (NB, not an fully qualified keyword). Would there be any interest in allowing colons inside the bracket syntax? (If not), is there any workaround, like pre-processing routes so that "/some/{:user/id}/path" is converted to "/some/{user/id}/path" before the paths are parsed?

DrLjótsson12:11:03

For now, I've made this function that pre-processes the route data

(defn bracket+colon->bracket
  [routes]
  (walk/postwalk
   (fn [form]
     (if (and (vector? form) (string? (first form)))
       (update form 0 (fn [s] (str/replace s "{:" "{")))
       form))
   routes))

DrLjótsson18:11:19

Hey! I feel a bit stupid - but am struggling with a problem to which there must be an obvious solution. My routes call functions that return links to other routes. I want to use reitit's bi-directional routing for this - but then I end up with cyclic dependencies. I.e., router requires namespace with response function, which requires the router to return a bidi-link. What is the obvious solution that I am missing?

wevrem20:11:17

You can use :as-alias in your :require

DrLjótsson20:11:06

Not sure I follow, but maybe I have misunderstood how bidi is supposed to work. I use the following to generate a string path from a route's :name

(rt/match->path (rt/match-by-name ns1/routes :route-name params))
For this to work, the function in ns2 that generates the response needs access to the routes, but they are in an ns1 that called the function in ns2 . So ns2can't require ns1

DrLjótsson20:11:55

I tried :as-alias but it doesn't compile. I thought :as-alias is only used for keywords, no?

wevrem20:11:29

The router itself (which is the first parameter to match-by-name) is available in the request map under the key :reitit.core/router. That clears up your need for ns1. I mostly use namespaced keywords for things like route-names, so I use :as-alias to let me refer to the route name, without creating a cycle. https://cljdoc.org/d/metosin/reitit/0.7.0-alpha7/doc/ring/reverse-routing#reverse-routing-with-ring

DrLjótsson20:11:45

Ah, awesome. I thought that there must be a reasonable solution to this 🙂 Thanks!