Merge pull request #585 from djblue/var-handler

Allow var handlers
This commit is contained in:
Joel Kaasinen 2024-03-15 10:35:22 +02:00 committed by GitHub
commit c67a748915
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 39 additions and 2 deletions

View file

@ -147,3 +147,19 @@ Let's apply a small change to our ```ns3```. We'll replace our router by two dif
And there you have it, dynamic during dev, performance at production. We have it all !
## Var handlers
You can use a var instead of a function as a `:handler`. This will
allow you to modify the handler function without rebuilding the reitit
router.
For example:
```clj
(def router
(ring/router
["/ping" {:get #'my-ns/handler}]))
```
Now you can reload `my-ns` or redefine `my-ns/handler` and the router
will use the new definition automatically.

View file

@ -28,6 +28,10 @@
:cljs function)
(expand [this _] {:handler this})
#?(:clj clojure.lang.Var
:cljs cljs.core.Var)
(expand [this _] {:handler this})
nil
(expand [_ _]))

View file

@ -38,7 +38,7 @@
;;
(s/def ::name keyword?)
(s/def ::handler fn?)
(s/def ::handler (s/or :fn fn? :var var?))
(s/def ::no-doc boolean?)
(s/def ::conflicting boolean?)
(s/def ::default-data

View file

@ -6,6 +6,9 @@
(:import (clojure.lang ExceptionInfo)
(reitit.core Router))))
(defn- var-handler [& _]
"var-handler")
(deftest reitit-test
(testing "routers handling wildcard paths"
@ -245,7 +248,11 @@
(let [router (r/router ["/ping" (constantly "ok")])
{:keys [result]} (r/match-by-path router "/ping")]
(is result)
(is (= "ok" (result))))))
(is (= "ok" (result))))
(testing "var handler gets expanded"
(let [router (r/router ["/ping" #'var-handler])
{:keys [result]} (r/match-by-path router "/ping")]
(is (= #'var-handler result))))))
(testing "custom router"
(let [router (r/router ["/ping"] {:router (fn [_ _]

View file

@ -52,6 +52,7 @@
["/api" {:middleware [api-mw]}
["/all" handler]
["/get" {:get handler}]
["/get-var" {:get {:handler #'handler}}]
["/users" {:middleware [[mw :users]]
:get handler
:post {:handler handler
@ -74,6 +75,10 @@
(app {:uri "/api/get" :request-method :get})))
(is (= nil (app {:uri "/api/get" :request-method :post}))))
(testing "var handler"
(is (= {:status 200, :body [:api :ok]}
(app {:uri "/api/get-var" :request-method :get}))))
(testing "expanded method handler"
(is (= {:status 200, :body [:api :users :ok]}
(app {:uri "/api/users" :request-method :get}))))

View file

@ -101,6 +101,11 @@
["/api" {:name "kikka"}]
{:validate rs/validate}))))
(testing "handler can be a var"
(is (r/router? (r/router
["/api" {:handler #'identity}]
{:validate rs/validate}))))
(testing "spec can be overridden"
(is (r/router? (r/router
["/api" {:handler "identity"}]