Router option to handle conflicts

This commit is contained in:
Tommi Reiman 2017-08-21 09:02:03 +03:00
parent 851e35ef52
commit f5f1104826
3 changed files with 47 additions and 20 deletions

View file

@ -393,13 +393,14 @@ 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`:
| key | description |
| -----------|-------------|
| -------------|-------------|
| `:path` | Base-path for routes (default `""`)
| `:routes` | Initial resolved routes (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`)
| `: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
| `:conflicts` | Function of `[route route] => side-effect` to handle conflicting routes (default `reitit.core/throw-on-conflicts!`)"
## Special thanks

View file

@ -66,6 +66,12 @@
(or (some #(if (impl/conflicting-routes? r %) [r %]) 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]
(if name #{name}))
@ -103,7 +109,8 @@
{:lookup name-lookup
:expand expand
:coerce (fn [route _] route)
:compile (fn [[_ {:keys [handler]}] _] handler)})
:compile (fn [[_ {:keys [handler]}] _] handler)
:conflicts throw-on-conflicts!})
(defn linear-router
"Creates a [[LinearRouter]] from resolved routes and optional
@ -192,17 +199,21 @@
[[LookupRouter]]. The following options are available:
| key | description |
| -----------|-------------|
| -------------|-------------|
| `:path` | Base-path for routes (default `\"\"`)
| `:routes` | Initial resolved routes (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`)
| `: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]
(router data {}))
([data opts]
(let [opts (meta-merge default-router-options 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))
linear-router lookup-router) routes opts))))

View file

@ -1,8 +1,8 @@
(ns reitit.core-test
(:require [clojure.test :refer [deftest testing is are]]
[reitit.core :as reitit #?@(:cljs [:refer [Match]])])
[reitit.core :as reitit #?@(:cljs [:refer [Match Routing]])])
#?(:clj
(:import (reitit.core Match)
(:import (reitit.core Match Routing)
(clojure.lang ExceptionInfo))))
(deftest reitit-test
@ -171,4 +171,19 @@
["/a/*b"]]
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)}))))))