mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 08:21:11 +00:00
Separate route-data-merge protocol
This commit is contained in:
parent
28707fff07
commit
d1c9ff638d
6 changed files with 34 additions and 26 deletions
|
|
@ -17,8 +17,7 @@
|
||||||
(-open-model [this model] "Returns a new model which allows extra keys in maps")
|
(-open-model [this model] "Returns a new model which allows extra keys in maps")
|
||||||
(-encode-error [this error] "Converts error in to a serializable format")
|
(-encode-error [this error] "Converts error in to a serializable format")
|
||||||
(-request-coercer [this type model] "Returns a `value format => value` request coercion function")
|
(-request-coercer [this type model] "Returns a `value format => value` request coercion function")
|
||||||
(-response-coercer [this model] "Returns a `value format => value` response coercion function")
|
(-response-coercer [this model] "Returns a `value format => value` response coercion function"))
|
||||||
(-route-data-merge [this acc k v]))
|
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defmethod print-method ::coercion [coercion ^Writer w]
|
(defmethod print-method ::coercion [coercion ^Writer w]
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@
|
||||||
(:import (java.util HashMap Map)
|
(:import (java.util HashMap Map)
|
||||||
(java.net URLEncoder URLDecoder))))
|
(java.net URLEncoder URLDecoder))))
|
||||||
|
|
||||||
|
(defprotocol RouteDataMerge
|
||||||
|
(-route-data-merge [this acc k v]))
|
||||||
|
|
||||||
(defn parse [path opts]
|
(defn parse [path opts]
|
||||||
(let [path #?(:clj (.intern ^String (trie/normalize path opts)) :cljs (trie/normalize path opts))
|
(let [path #?(:clj (.intern ^String (trie/normalize path opts)) :cljs (trie/normalize path opts))
|
||||||
path-parts (trie/split-path path opts)
|
path-parts (trie/split-path path opts)
|
||||||
|
|
@ -67,13 +70,15 @@
|
||||||
(let [;; Find last the effective :coercion value
|
(let [;; Find last the effective :coercion value
|
||||||
;; for the route, and then use the cocercion
|
;; for the route, and then use the cocercion
|
||||||
;; instance for route data merge implementation.
|
;; instance for route data merge implementation.
|
||||||
|
;; TODO: other options/keys should also be able to control
|
||||||
|
;; merge?
|
||||||
coercion (->> x
|
coercion (->> x
|
||||||
reverse
|
reverse
|
||||||
(some (fn [[k v]]
|
(some (fn [[k v]]
|
||||||
(when (= :coercion k)
|
(when (= :coercion k)
|
||||||
v))))
|
v))))
|
||||||
route-data-merge (if coercion
|
route-data-merge (if coercion
|
||||||
#((resolve 'reitit.coercion/-route-data-merge) coercion %1 %2 %3)
|
#(-route-data-merge coercion %1 %2 %3)
|
||||||
default-route-data-merge)]
|
default-route-data-merge)]
|
||||||
(reduce
|
(reduce
|
||||||
(fn [acc [k v]]
|
(fn [acc [k v]]
|
||||||
|
|
@ -85,8 +90,7 @@
|
||||||
x)))
|
x)))
|
||||||
|
|
||||||
(defn resolve-routes [raw-routes {:keys [coerce] :as opts}]
|
(defn resolve-routes [raw-routes {:keys [coerce] :as opts}]
|
||||||
(cond->> (->> (walk raw-routes opts)
|
(cond->> (->> (walk raw-routes opts) (map-data merge-data))
|
||||||
(map-data merge-data))
|
|
||||||
coerce (into [] (keep #(coerce % opts)))))
|
coerce (into [] (keep #(coerce % opts)))))
|
||||||
|
|
||||||
(defn path-conflicting-routes [routes opts]
|
(defn path-conflicting-routes [routes opts]
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
[malli.core :as m]
|
[malli.core :as m]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[clojure.walk :as walk]
|
[clojure.walk :as walk]
|
||||||
[meta-merge.core :as mm]))
|
[reitit.impl :as impl]))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; coercion
|
;; coercion
|
||||||
|
|
@ -181,9 +181,10 @@
|
||||||
(-coercer (compile schema options) type transformers :decode opts))
|
(-coercer (compile schema options) type transformers :decode opts))
|
||||||
(-response-coercer [_ schema]
|
(-response-coercer [_ schema]
|
||||||
(-coercer (compile schema options) :response transformers :encode opts))
|
(-coercer (compile schema options) :response transformers :encode opts))
|
||||||
|
impl/RouteDataMerge
|
||||||
(-route-data-merge [_ acc k v]
|
(-route-data-merge [_ acc k v]
|
||||||
(case k
|
(case k
|
||||||
:parameters (assoc acc :parameters (merge-with mu/merge (:parameters acc) v))
|
:parameters (assoc acc :parameters (merge-with mu/merge (:parameters acc) v))
|
||||||
(mm/meta-merge acc {k v})))))))
|
(impl/default-route-data-merge acc k v)))))))
|
||||||
|
|
||||||
(def coercion (create default-options))
|
(def coercion (create default-options))
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@
|
||||||
(-response-coercer [this schema]
|
(-response-coercer [this schema]
|
||||||
(if (coerce-response? schema)
|
(if (coerce-response? schema)
|
||||||
(coercion/-request-coercer this :response schema)))
|
(coercion/-request-coercer this :response schema)))
|
||||||
|
impl/RouteDataMerge
|
||||||
(-route-data-merge [this acc k v]
|
(-route-data-merge [this acc k v]
|
||||||
(impl/default-route-data-merge acc k v))))
|
(impl/default-route-data-merge acc k v))))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@
|
||||||
(-response-coercer [this spec]
|
(-response-coercer [this spec]
|
||||||
(if (coerce-response? spec)
|
(if (coerce-response? spec)
|
||||||
(coercion/-request-coercer this :response spec)))
|
(coercion/-request-coercer this :response spec)))
|
||||||
|
impl/RouteDataMerge
|
||||||
(-route-data-merge [this acc k v]
|
(-route-data-merge [this acc k v]
|
||||||
(impl/default-route-data-merge acc k v))))
|
(impl/default-route-data-merge acc k v))))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,25 +190,27 @@
|
||||||
[:view 'b]
|
[:view 'b]
|
||||||
[:controllers ^:replace [2]]])))
|
[:controllers ^:replace [2]]])))
|
||||||
|
|
||||||
(is (= {:a schema/Str
|
(testing "Schema - regular merge"
|
||||||
:b schema/Str}
|
(is (= {:a schema/Str
|
||||||
(-> (impl/merge-data "/"
|
:b schema/Str}
|
||||||
[[:parameters {:path {:a schema/Str}}]
|
(-> (impl/merge-data "/"
|
||||||
[:parameters {:path {:b schema/Str}}]])
|
[[:parameters {:path {:a schema/Str}}]
|
||||||
:parameters
|
[:parameters {:path {:b schema/Str}}]])
|
||||||
:path)))
|
:parameters
|
||||||
|
:path))))
|
||||||
|
|
||||||
(is (= [:map
|
(testing "Malli schema merge - mu/merge"
|
||||||
[:a 'string?]
|
(is (= [:map
|
||||||
[:b 'int?]]
|
[:a 'string?]
|
||||||
(-> (impl/merge-data "/"
|
[:b 'int?]]
|
||||||
[[:coercion rcm/coercion]
|
(-> (impl/merge-data "/"
|
||||||
[:parameters {:path [:map [:a 'string?]]}]
|
[[:coercion rcm/coercion]
|
||||||
[:parameters {:path [:map [:b 'int?]]}]])
|
[:parameters {:path [:map [:a 'string?]]}]
|
||||||
:parameters
|
[:parameters {:path [:map [:b 'int?]]}]])
|
||||||
:path
|
:parameters
|
||||||
;; Merge returns schema object, convert back to form for comparison
|
:path
|
||||||
malli.core/form)))
|
;; Merge returns schema object, convert back to form for comparison
|
||||||
|
malli.core/form))))
|
||||||
|
|
||||||
;; TODO: Also test and support Schema and spec merging
|
;; TODO: Spec
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue