mirror of
https://github.com/metosin/reitit.git
synced 2025-12-18 17:01:11 +00:00
Router option to handle conflicts
This commit is contained in:
parent
851e35ef52
commit
f5f1104826
3 changed files with 47 additions and 20 deletions
17
README.md
17
README.md
|
|
@ -392,14 +392,15 @@ Authorized access to guarded route:
|
||||||
|
|
||||||
Routers can be configured via options. Options allow things like [`clojure.spec`](https://clojure.org/about/spec) validation for meta-data and fast, compiled handlers. The following options are available for the `reitit.core/router`:
|
Routers can be configured via options. Options allow things like [`clojure.spec`](https://clojure.org/about/spec) validation for meta-data and fast, compiled handlers. The following options are available for the `reitit.core/router`:
|
||||||
|
|
||||||
| key | description |
|
| key | description |
|
||||||
| -----------|-------------|
|
| -------------|-------------|
|
||||||
| `:path` | Base-path for routes (default `""`)
|
| `:path` | Base-path for routes (default `""`)
|
||||||
| `:routes` | Initial resolved routes (default `[]`)
|
| `:routes` | Initial resolved routes (default `[]`)
|
||||||
| `:meta` | Initial expanded route-meta vector (default `[]`)
|
| `:meta` | Initial expanded route-meta vector (default `[]`)
|
||||||
| `:expand` | Function of `arg opts => meta` to expand route arg to route meta-data (default `reitit.core/expand`)
|
| `:expand` | Function of `arg opts => meta` to expand route arg to route meta-data (default `reitit.core/expand`)
|
||||||
| `:coerce` | Function of `route opts => route` to coerce resolved route, can throw or return `nil`
|
| `:coerce` | Function of `route opts => route` to coerce resolved route, can throw or return `nil`
|
||||||
| `:compile` | Function of `route opts => handler` to compile a route handler
|
| `:compile` | Function of `route opts => handler` to compile a route handler
|
||||||
|
| `:conflicts` | Function of `[route route] => side-effect` to handle conflicting routes (default `reitit.core/throw-on-conflicts!`)"
|
||||||
|
|
||||||
## Special thanks
|
## Special thanks
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,12 @@
|
||||||
(or (some #(if (impl/conflicting-routes? r %) [r %]) rest)
|
(or (some #(if (impl/conflicting-routes? r %) [r %]) rest)
|
||||||
(recur rest)))))
|
(recur rest)))))
|
||||||
|
|
||||||
|
(defn throw-on-conflicts! [routes]
|
||||||
|
(throw
|
||||||
|
(ex-info
|
||||||
|
(str "router contains conflicting routes: " routes)
|
||||||
|
{:routes routes})))
|
||||||
|
|
||||||
(defn name-lookup [[_ {:keys [name]}] opts]
|
(defn name-lookup [[_ {:keys [name]}] opts]
|
||||||
(if name #{name}))
|
(if name #{name}))
|
||||||
|
|
||||||
|
|
@ -103,7 +109,8 @@
|
||||||
{:lookup name-lookup
|
{:lookup name-lookup
|
||||||
:expand expand
|
:expand expand
|
||||||
:coerce (fn [route _] route)
|
:coerce (fn [route _] route)
|
||||||
:compile (fn [[_ {:keys [handler]}] _] handler)})
|
:compile (fn [[_ {:keys [handler]}] _] handler)
|
||||||
|
:conflicts throw-on-conflicts!})
|
||||||
|
|
||||||
(defn linear-router
|
(defn linear-router
|
||||||
"Creates a [[LinearRouter]] from resolved routes and optional
|
"Creates a [[LinearRouter]] from resolved routes and optional
|
||||||
|
|
@ -191,18 +198,22 @@
|
||||||
If routes contain wildcards, a [[LinearRouter]] is used, otherwise a
|
If routes contain wildcards, a [[LinearRouter]] is used, otherwise a
|
||||||
[[LookupRouter]]. The following options are available:
|
[[LookupRouter]]. The following options are available:
|
||||||
|
|
||||||
| key | description |
|
| key | description |
|
||||||
| -----------|-------------|
|
| -------------|-------------|
|
||||||
| `:path` | Base-path for routes (default `\"\"`)
|
| `:path` | Base-path for routes (default `\"\"`)
|
||||||
| `:routes` | Initial resolved routes (default `[]`)
|
| `:routes` | Initial resolved routes (default `[]`)
|
||||||
| `:meta` | Initial expanded route-meta vector (default `[]`)
|
| `:meta` | Initial expanded route-meta vector (default `[]`)
|
||||||
| `:expand` | Function of `arg opts => meta` to expand route arg to route meta-data (default `reitit.core/expand`)
|
| `:expand` | Function of `arg opts => meta` to expand route arg to route meta-data (default `reitit.core/expand`)
|
||||||
| `:coerce` | Function of `route opts => route` to coerce resolved route, can throw or return `nil`
|
| `:coerce` | Function of `route opts => route` to coerce resolved route, can throw or return `nil`
|
||||||
| `:compile` | Function of `route opts => handler` to compile a route handler"
|
| `:compile` | Function of `route opts => handler` to compile a route handler
|
||||||
|
| `:conflicts` | Function of `[route route] => side-effect` to handle conflicting routes (default `reitit.core/throw-on-conflicts!`)"
|
||||||
([data]
|
([data]
|
||||||
(router data {}))
|
(router data {}))
|
||||||
([data opts]
|
([data opts]
|
||||||
(let [opts (meta-merge default-router-options opts)
|
(let [opts (meta-merge default-router-options opts)
|
||||||
routes (resolve-routes data opts)]
|
routes (resolve-routes data opts)]
|
||||||
|
(when-let [conflicts (:conflicts opts)]
|
||||||
|
(when-let [conflicting-routes (first-conflicting-routes routes)]
|
||||||
|
(conflicts conflicting-routes)))
|
||||||
((if (some impl/contains-wilds? (map first routes))
|
((if (some impl/contains-wilds? (map first routes))
|
||||||
linear-router lookup-router) routes opts))))
|
linear-router lookup-router) routes opts))))
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
(ns reitit.core-test
|
(ns reitit.core-test
|
||||||
(:require [clojure.test :refer [deftest testing is are]]
|
(:require [clojure.test :refer [deftest testing is are]]
|
||||||
[reitit.core :as reitit #?@(:cljs [:refer [Match]])])
|
[reitit.core :as reitit #?@(:cljs [:refer [Match Routing]])])
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(:import (reitit.core Match)
|
(:import (reitit.core Match Routing)
|
||||||
(clojure.lang ExceptionInfo))))
|
(clojure.lang ExceptionInfo))))
|
||||||
|
|
||||||
(deftest reitit-test
|
(deftest reitit-test
|
||||||
|
|
@ -171,4 +171,19 @@
|
||||||
["/a/*b"]]
|
["/a/*b"]]
|
||||||
|
|
||||||
true [["/v2/public/messages/dataset/bulk"]
|
true [["/v2/public/messages/dataset/bulk"]
|
||||||
["/v2/public/messages/dataset/:dataset-id"]]))
|
["/v2/public/messages/dataset/:dataset-id"]])
|
||||||
|
|
||||||
|
(testing "router with conflicting routes"
|
||||||
|
(testing "throws by default"
|
||||||
|
(is (thrown-with-msg?
|
||||||
|
ExceptionInfo
|
||||||
|
#"router contains conflicting routes"
|
||||||
|
(reitit/router
|
||||||
|
[["/a"] ["/a"]]))))
|
||||||
|
(testing "can be configured to ignore"
|
||||||
|
(is (instance?
|
||||||
|
Routing
|
||||||
|
(reitit/router
|
||||||
|
[["/a"] ["/a"]]
|
||||||
|
{:conflicts (constantly nil)}))))))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue