Skip to content

Commit

Permalink
Support for top-level middleware in reitit-ring
Browse files Browse the repository at this point in the history
  • Loading branch information
ikitommi committed Sep 22, 2018
1 parent 75c5dc4 commit 158695d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 31 deletions.
68 changes: 37 additions & 31 deletions modules/reitit-ring/src/reitit/ring.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
16 changes: 16 additions & 0 deletions test/cljc/reitit/ring_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 158695d

Please sign in to comment.