Hello reititians :-) I’ve been searching reitit docs for matching a route with configured a :host
key in its data against the actual window’s host but couldn’t find anything related, I ended up with a custom compiler that I pass as option to reitit.core/router
, like:
(defn host-match-compiler [host]
(reify reitit.trie/TrieCompiler
(linear-matcher [_ matchers _]
(let [size (count matchers)]
(reify reitit.trie/Matcher
(match [_ i max path]
(loop [j 0]
(when (< j size)
(let [m (reitit.trie/match (get matchers j) i max path)]
(or (when (and m (= host (-> m :data :data :host))) m)
(recur (inc j))))))))))
as we’re currenlty using a linear-matcher. Would anyone have a better suggestion than this? how could we move the host matching logic inside the reitit.trie/Matcher
’s match
implementation?the router in question is used on the client side
@andrea712 excellect question. You could also write an unitlity on top of the router that selects a router based on the host. Something like:
(def host->router
(->> [["/out" {:host "0.0.0.0"}
["/ping"]
["/pong"]]
["/local" {:host "127.0.0.1"}
["/pong"]]]
(r/router)
(r/routes)
(group-by (comp :host second))
(map #(update % 1 r/router))
(into {})))
(-> "0.0.0.0" host->router (r/match-by-path "/out/ping"))
; #reitit.core.Match{:template "/out/ping", :data {:host "0.0.0.0"}, :result nil, :path-params {}, :path "/out/ping"}
(-> "0.0.0.0" host->router (r/match-by-path "/local/ping"))
; => nil
e.g. you can extract the flattened route tree with r/routes
and r/compiled-routes
and the options (if needed) with r/options
.
@ikitommi thanks a lot for the suggestion! I’ll check if it applies to our use case, but it looks like less of a hack than ours