Move route-data merge impl to coercion protocol

This commit is contained in:
Juho Teperi 2021-12-26 00:31:52 +02:00
parent 5529e5acf0
commit 28707fff07
7 changed files with 45 additions and 31 deletions

View file

@ -17,7 +17,8 @@
(-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")
(-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
(defmethod print-method ::coercion [coercion ^Writer w]

View file

@ -360,8 +360,7 @@
| `:validate` | Function of `routes opts => ()` to validate route (data) via side-effects
| `:conflicts` | Function of `{route #{route}} => ()` to handle conflicting routes
| `:exception` | Function of `Exception => Exception ` to handle creation time exceptions (default `reitit.exception/exception`)
| `:router` | Function of `routes opts => router` to override the actual router implementation
| `:merge` | Function of `route-data key value` to add new kv pair to route-data map. Default uses merge-merge."
| `:router` | Function of `routes opts => router` to override the actual router implementation"
([raw-routes]
(router raw-routes {}))
([raw-routes opts]

View file

@ -63,18 +63,30 @@
(defn default-route-data-merge [acc k v]
(mm/meta-merge acc {k v}))
(defn merge-data [route-data-merge p x]
(reduce
(fn [acc [k v]]
(try
(route-data-merge acc k v)
(catch #?(:clj Exception, :cljs js/Error) e
(ex/fail! ::merge-data {:path p, :left acc, :right {k v}, :exception e}))))
{} x))
(defn merge-data [p x]
(let [;; Find last the effective :coercion value
;; for the route, and then use the cocercion
;; instance for route data merge implementation.
coercion (->> x
reverse
(some (fn [[k v]]
(when (= :coercion k)
v))))
route-data-merge (if coercion
#((resolve 'reitit.coercion/-route-data-merge) coercion %1 %2 %3)
default-route-data-merge)]
(reduce
(fn [acc [k v]]
(try
(route-data-merge acc k v)
(catch #?(:clj Exception, :cljs js/Error) e
(ex/fail! ::merge-data {:path p, :left acc, :right {k v}, :exception e}))))
{}
x)))
(defn resolve-routes [raw-routes {:keys [coerce _merge] :as opts}]
(defn resolve-routes [raw-routes {:keys [coerce] :as opts}]
(cond->> (->> (walk raw-routes opts)
(map-data (partial merge-data (or (:merge opts) default-route-data-merge))))
(map-data merge-data))
coerce (into [] (keep #(coerce % opts)))))
(defn path-conflicting-routes [routes opts]

View file

@ -180,11 +180,10 @@
(-request-coercer [_ type schema]
(-coercer (compile schema options) type transformers :decode opts))
(-response-coercer [_ schema]
(-coercer (compile schema options) :response transformers :encode opts))))))
(-coercer (compile schema options) :response transformers :encode opts))
(-route-data-merge [_ acc k v]
(case k
:parameters (assoc acc :parameters (merge-with mu/merge (:parameters acc) v))
(mm/meta-merge acc {k v})))))))
(def coercion (create default-options))
(defn route-data-merge [acc k v]
(case k
:parameters (assoc acc :parameters (merge-with mu/merge (:parameters acc) v))
(mm/meta-merge acc {k v})))

View file

@ -7,7 +7,8 @@
[schema-tools.coerce :as stc]
[schema-tools.swagger.core :as swagger]
[reitit.coercion :as coercion]
[clojure.set :as set]))
[clojure.set :as set]
[reitit.impl :as impl]))
(def string-coercion-matcher
stc/string-coercion-matcher)
@ -94,6 +95,8 @@
value))))
(-response-coercer [this schema]
(if (coerce-response? schema)
(coercion/-request-coercer this :response schema)))))
(coercion/-request-coercer this :response schema)))
(-route-data-merge [this acc k v]
(impl/default-route-data-merge acc k v))))
(def coercion (create default-options))

View file

@ -4,6 +4,7 @@
[spec-tools.data-spec :as ds #?@(:cljs [:refer [Maybe]])]
[spec-tools.swagger.core :as swagger]
[reitit.coercion :as coercion]
[reitit.impl :as impl]
[clojure.set :as set])
#?(:clj
(:import (spec_tools.core Spec)
@ -135,6 +136,8 @@
value))))
(-response-coercer [this spec]
(if (coerce-response? spec)
(coercion/-request-coercer this :response spec)))))
(coercion/-request-coercer this :response spec)))
(-route-data-merge [this acc k v]
(impl/default-route-data-merge acc k v))))
(def coercion (create default-options))

View file

@ -176,8 +176,7 @@
(deftest merge-data-test
(is (= {:view 'b
:controllers [1 2]}
(impl/merge-data impl/default-route-data-merge
"/"
(impl/merge-data "/"
[[:view 'a]
[:controllers [1]]
[:view 'b]
@ -185,8 +184,7 @@
(is (= {:view 'b
:controllers [2]}
(impl/merge-data impl/default-route-data-merge
"/"
(impl/merge-data "/"
[[:view 'a]
[:controllers [1]]
[:view 'b]
@ -194,8 +192,7 @@
(is (= {:a schema/Str
:b schema/Str}
(-> (impl/merge-data rcm/route-data-merge
"/"
(-> (impl/merge-data "/"
[[:parameters {:path {:a schema/Str}}]
[:parameters {:path {:b schema/Str}}]])
:parameters
@ -204,9 +201,9 @@
(is (= [:map
[:a 'string?]
[:b 'int?]]
(-> (impl/merge-data rcm/route-data-merge
"/"
[[:parameters {:path [:map [:a 'string?]]}]
(-> (impl/merge-data "/"
[[:coercion rcm/coercion]
[:parameters {:path [:map [:a 'string?]]}]
[:parameters {:path [:map [:b 'int?]]}]])
:parameters
:path