From a7cd1cf398c664536090277a303887bb264905a2 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Wed, 4 Dec 2019 08:10:21 +0200 Subject: [PATCH] response endoding, WIP: tests --- modules/reitit-core/src/reitit/coercion.cljc | 3 +- .../src/reitit/coercion/malli.cljc | 68 ++++++++++++------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/modules/reitit-core/src/reitit/coercion.cljc b/modules/reitit-core/src/reitit/coercion.cljc index 737847dc..07777db7 100644 --- a/modules/reitit-core/src/reitit/coercion.cljc +++ b/modules/reitit-core/src/reitit/coercion.cljc @@ -92,7 +92,7 @@ (defn response-coercer [coercion body {:keys [extract-response-format] :or {extract-response-format extract-response-format-default}}] (if coercion - (let [coercer (-response-coercer coercion body)] + (if-let [coercer (-response-coercer coercion body)] (fn [request response] (let [format (extract-response-format request response) value (:body response) @@ -130,6 +130,7 @@ (defn response-coercers [coercion responses opts] (->> (for [[status {:keys [body]}] responses :when body] [status (response-coercer coercion body opts)]) + (filter second) (into {}))) ;; diff --git a/modules/reitit-malli/src/reitit/coercion/malli.cljc b/modules/reitit-malli/src/reitit/coercion/malli.cljc index c0f7a56c..84f709c2 100644 --- a/modules/reitit-malli/src/reitit/coercion/malli.cljc +++ b/modules/reitit-malli/src/reitit/coercion/malli.cljc @@ -5,6 +5,10 @@ [malli.core :as m] [clojure.set :as set])) +;; +;; coercion +;; + (defrecord Coercer [decoder encoder validator explainer]) (def string-transformer @@ -19,6 +23,37 @@ (defmulti coerce-response? identity :default ::default) (defmethod coerce-response? ::default [_] true) +(defn- -coercer [schema type transformers f] + (if schema + (let [->coercer (fn [t] (if t (->Coercer (m/decoder schema t) + (m/encoder schema t) + (m/validator schema) + (m/explainer schema)))) + {:keys [formats default]} (transformers type) + default-coercer (->coercer default) + format-coercers (->> (for [[f t] formats] [f (->coercer t)]) (into {})) + get-coercer (if (seq format-coercers) + (fn [format] (or (get format-coercers format) default-coercer)) + (constantly default-coercer))] + (if default-coercer + (fn [value format] + (if-let [coercer (get-coercer format)] + (let [transform (f coercer) + validator (:validator coercer) + transformed (transform value)] + (if (validator transformed) + transformed + (let [explainer (:explainer coercer) + errors (explainer transformed)] + (coercion/map->CoercionError + {:schema schema + :errors errors})))) + value)))))) + +;; +;; swagger +;; + (defmulti extract-parameter (fn [in _] in)) (defmethod extract-parameter :body [_ schema] @@ -42,6 +77,10 @@ schema)) properties))) +;; +;; public api +;; + (def default-options {:coerce-response? coerce-response? :transformers {:body {:default default-transformer @@ -82,32 +121,9 @@ (-open-model [_ schema] schema) (-encode-error [_ error] error) (-request-coercer [_ type schema] - (if schema - (let [->coercer (fn [t] (->Coercer (m/decoder schema t) - (m/encoder schema t) - (m/validator schema) - (m/explainer schema))) - {:keys [formats default]} (transformers type) - default-coercer (->coercer default) - format-coercers (->> (for [[f t] formats] [f (->coercer t)]) (into {})) - get-coercer (if (seq format-coercers) - (fn [format] (or (get format-coercers format) default-coercer)) - (constantly default-coercer))] - (fn [value format] - (if-let [coercer (get-coercer format)] - (let [decoder (:decoder coercer) - validator (:validator coercer) - decoded (decoder value)] - (if (validator decoded) - decoded - (let [explainer (:explainer coercer) - errors (explainer decoded)] - (coercion/map->CoercionError - {:schema schema - :errors errors})))) - value))))) - (-response-coercer [this schema] + (-coercer schema type transformers :decoder)) + (-response-coercer [_ schema] (if (coerce-response? schema) - (coercion/-request-coercer this :response schema))))) + (-coercer schema :response transformers :encoder))))) (def coercion (create default-options))