diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index f74b0e85..3b08e113 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -177,41 +177,47 @@ (create handler))))) (defn ring-handler - "Creates a ring-handler out of a ring-router. - Supports both 1 (sync) and 3 (async) arities. - Optionally takes a ring-handler which is called - in no route matches." + "Creates a ring-handler out of a router, optional default ring-handler + and options map, with the following keys: + + | key | description | + | --------------|-------------| + | `:middleware` | Optional sequence of middleware that are wrap the [[ring-handler]]" ([router] (ring-handler router nil)) ([router default-handler] - (let [default-handler (or default-handler (fn ([_]) ([_ respond _] (respond nil))))] + (ring-handler router default-handler nil)) + ([router default-handler {:keys [middleware]}] + (let [default-handler (or default-handler (fn ([_]) ([_ respond _] (respond nil)))) + wrap (if middleware (partial middleware/chain middleware) identity)] (with-meta - (fn - ([request] - (if-let [match (r/match-by-path router (:uri request))] - (let [method (:request-method request) - path-params (:path-params match) - result (:result match) - handler (-> result method :handler (or default-handler)) - request (-> request - (impl/fast-assoc :path-params path-params) - (impl/fast-assoc ::r/match match) - (impl/fast-assoc ::r/router router))] - (or (handler request) (default-handler request))) - (default-handler request))) - ([request respond raise] - (if-let [match (r/match-by-path router (:uri request))] - (let [method (:request-method request) - path-params (:path-params match) - result (:result match) - handler (-> result method :handler (or default-handler)) - request (-> request - (impl/fast-assoc :path-params path-params) - (impl/fast-assoc ::r/match match) - (impl/fast-assoc ::r/router router))] - ((routes handler default-handler) request respond raise)) - (default-handler request respond raise)) - nil)) + (wrap + (fn + ([request] + (if-let [match (r/match-by-path router (:uri request))] + (let [method (:request-method request) + path-params (:path-params match) + result (:result match) + handler (-> result method :handler (or default-handler)) + request (-> request + (impl/fast-assoc :path-params path-params) + (impl/fast-assoc ::r/match match) + (impl/fast-assoc ::r/router router))] + (or (handler request) (default-handler request))) + (default-handler request))) + ([request respond raise] + (if-let [match (r/match-by-path router (:uri request))] + (let [method (:request-method request) + path-params (:path-params match) + result (:result match) + handler (-> result method :handler (or default-handler)) + request (-> request + (impl/fast-assoc :path-params path-params) + (impl/fast-assoc ::r/match match) + (impl/fast-assoc ::r/router router))] + ((routes handler default-handler) request respond raise)) + (default-handler request respond raise)) + nil))) {::r/router router})))) (defn get-router [handler] diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 60bdb2e4..2038855d 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -78,6 +78,22 @@ (is (= {:status 200, :body [:api :users :post :ok]} @result)))))) + (testing "with top-level middleware" + (let [router (ring/router + ["/api" {:middleware [[mw :api]]} + ["/get" {:get handler}]]) + app (ring/ring-handler router nil {:middleware [[mw :top]]})] + + (testing "router can be extracted" + (is (= router (ring/get-router app)))) + + (testing "not found" + (is (= nil (app {:uri "/favicon.ico"})))) + + (testing "on match" + (is (= {:status 200, :body [:top :api :ok]} + (app {:uri "/api/get" :request-method :get})))))) + (testing "named routes" (let [router (ring/router [["/api"