From 11534551da0ba7853163cf4f2c11679ac2b25bc4 Mon Sep 17 00:00:00 2001 From: dgb23 Date: Tue, 7 Mar 2023 00:13:15 +0100 Subject: [PATCH] Update composing_routers.md I wondered how one would wrap a ring handler that can be recreated at runtime without restarting the server. @ikitommi suggested to use the recently added `reloading-ring-handler` as a starting point. I propose a small example here that illustrates the pattern. --- doc/advanced/composing_routers.md | 46 ++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/doc/advanced/composing_routers.md b/doc/advanced/composing_routers.md index 4a0f37c9..87a14ea0 100644 --- a/doc/advanced/composing_routers.md +++ b/doc/advanced/composing_routers.md @@ -405,9 +405,53 @@ All the beer-routes now match in constant time. |-----------------|---------|----------------------- | `/beers/sahti` | 40ns | static +### Wrapping a swappable ring handler + +In order for a ring handler to be recomposed, we can wrap it into a handler that dereferences it on request. + +```clj +(defn deref-handler [rf] + (fn + ([request] (@rf request)) + ([request respond raise] (@rf request respond raise)))) +``` + +A simplified beer router version that creates a ring-handler. + +```clj +(defn create-ring-handler [beers] + (ring/ring-handler + (ring/router + [["/beers" + (when (seq beers) + (for [beer beers] + [(str "/" beer) + {:get (fn [_] {:status 200 :body beer})}]))]]))) + +(def ring-handler + (atom (create-ring-handler nil))) + +(defn reset-router! [beers] + (reset! ring-handler (create-ring-handler beers))) +``` + +We don't have any matching routes yet. + +```clj +((deref-handler ring-handler) {:request-method :get :uri "/beers/lager"}) +; nil +``` + +But we can add them later. + +```clj +(reset-router! ["lager"]) +((deref-handler ring-handler) {:request-method :get :uri "/beers/lager"}) +; {:status 200, :body "lager"} +``` + ## TODO -* add an example how to do dynamic routing with `reitit-ring` * maybe create a `recursive-router` into a separate ns with all `Router` functions implemented correctly? maybe not... * add `reitit.core/merge-routes` to effectively merge routes with route data