diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e3bca0c..d49cbb30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,25 @@ We use [Break Versioning][breakver]. The version numbers follow a `.coercer (fn [t] (let [decoder (if t (m/decoder schema options t) identity) @@ -48,7 +48,6 @@ (-explain [_ value] (explainer value))))) {:keys [formats default]} (transformers type) default-coercer (->coercer default) - encode (or encoder (fn [value _format] value)) format-coercers (some->> (for [[f t] formats] [f (->coercer t)]) (filter second) (seq) (into {})) get-coercer (cond format-coercers (fn [format] (or (get format-coercers format) default-coercer)) default-coercer (constantly default-coercer))] @@ -66,14 +65,14 @@ value)) ;; encode: decode -> validate -> encode (fn [value format] - (if-let [coercer (get-coercer format)] - (let [transformed (-decode coercer value)] + (let [transformed (-decode default-coercer value)] + (if-let [coercer (get-coercer format)] (if (-validate coercer transformed) - (encode transformed format) + (-encode coercer transformed) (let [error (-explain coercer transformed)] (coercion/map->CoercionError - (assoc error :transformed transformed))))) - value))))))) + (assoc error :transformed transformed)))) + value)))))))) ;; ;; swagger @@ -106,11 +105,13 @@ ;; public api ;; +;; TODO: this is much too compöex (def default-options {:transformers {:body {:default default-transformer-provider :formats {"application/json" json-transformer-provider}} :string {:default string-transformer-provider} - :response {:default default-transformer-provider}} + :response {:default default-transformer-provider + :formats {"application/json" json-transformer-provider}}} ;; set of keys to include in error messages :error-keys #{:type :coercion :in :schema :value :errors :humanized #_:transformed} ;; schema identity function (default: close all map schemas) @@ -176,10 +177,8 @@ (seq error-keys) (select-keys error-keys) encode-error (encode-error))) (-request-coercer [_ type schema] - (-coercer (compile schema options) type transformers :decode nil opts)) + (-coercer (compile schema options) type transformers :decode opts)) (-response-coercer [_ schema] - (let [schema (compile schema options) - encoder (-coercer schema :body transformers :encode nil opts)] - (-coercer schema :response transformers :encode encoder opts))))))) + (-coercer (compile schema options) :response transformers :encode opts)))))) (def coercion (create default-options)) diff --git a/project.clj b/project.clj index 3011edd7..7e9f8d35 100644 --- a/project.clj +++ b/project.clj @@ -27,28 +27,28 @@ [metosin/reitit-frontend "0.5.13"] [metosin/reitit-sieppari "0.5.13"] [metosin/reitit-pedestal "0.5.13"] - [metosin/ring-swagger-ui "3.36.0"] + [metosin/ring-swagger-ui "3.46.0"] [metosin/spec-tools "0.10.5"] [metosin/schema-tools "0.12.3"] [metosin/muuntaja "0.6.8"] - [metosin/jsonista "0.3.1"] + [metosin/jsonista "0.3.3"] [metosin/sieppari "0.0.0-alpha13"] - [metosin/malli "0.3.0"] + [metosin/malli "0.5.1"] ;; https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111 - [com.fasterxml.jackson.core/jackson-core "2.12.1"] - [com.fasterxml.jackson.core/jackson-databind "2.12.1"] + [com.fasterxml.jackson.core/jackson-core "2.12.4"] + [com.fasterxml.jackson.core/jackson-databind "2.12.4"] [meta-merge "1.0.0"] - [fipp "0.6.23" :exclusions [org.clojure/core.rrb-vector]] + [fipp "0.6.24" :exclusions [org.clojure/core.rrb-vector]] [expound "0.8.9"] [lambdaisland/deep-diff "0.0-47"] [com.bhauman/spell-spec "0.1.2"] - [ring/ring-core "1.9.1"] + [ring/ring-core "1.9.4"] - [io.pedestal/pedestal.service "0.5.8"]] + [io.pedestal/pedestal.service "0.5.9"]] - :plugins [[jonase/eastwood "0.3.14"] + :plugins [[jonase/eastwood "0.9.6"] ;[lein-virgil "0.1.7"] [lein-doo "0.1.11"] [lein-cljsbuild "1.1.8"] @@ -85,33 +85,33 @@ [metosin/spec-tools "0.10.5"] [metosin/muuntaja "0.6.8"] [metosin/sieppari "0.0.0-alpha13"] - [metosin/jsonista "0.3.1"] - [metosin/malli "0.2.1"] + [metosin/jsonista "0.3.3"] + [metosin/malli "0.5.1"] [lambdaisland/deep-diff "0.0-47"] [meta-merge "1.0.0"] [com.bhauman/spell-spec "0.1.2"] [expound "0.8.9"] - [fipp "0.6.23"] + [fipp "0.6.24"] [orchestra "2021.01.01-1"] - [ring "1.9.1"] + [ring "1.9.4"] [ikitommi/immutant-web "3.0.0-alpha1"] [metosin/ring-http-response "0.9.2"] - [metosin/ring-swagger-ui "3.36.0"] + [metosin/ring-swagger-ui "3.46.0"] [criterium "0.4.6"] [org.clojure/test.check "1.1.0"] [org.clojure/tools.namespace "1.1.0"] - [com.gfredericks/test.chuck "0.2.10"] + [com.gfredericks/test.chuck "0.2.11"] - [io.pedestal/pedestal.service "0.5.8"] + [io.pedestal/pedestal.service "0.5.9"] - [org.clojure/core.async "1.3.610"] + [org.clojure/core.async "1.3.618"] [manifold "0.1.8"] - [funcool/promesa "6.0.0"] + [funcool/promesa "6.0.2"] - [com.clojure-goes-fast/clj-async-profiler "0.5.0"] + [com.clojure-goes-fast/clj-async-profiler "0.5.1"] [ring-cors "0.1.13"] [com.bhauman/rebel-readline "0.1.4"]]} @@ -121,18 +121,18 @@ "-Dclojure.compiler.direct-linking=true"] :test-paths ["perf-test/clj"] :dependencies [[compojure "1.6.2"] - [ring/ring-defaults "0.3.2"] + [ring/ring-defaults "0.3.3"] [ikitommi/immutant-web "3.0.0-alpha1"] - [io.pedestal/pedestal.service "0.5.8"] - [io.pedestal/pedestal.jetty "0.5.8"] + [io.pedestal/pedestal.service "0.5.9"] + [io.pedestal/pedestal.jetty "0.5.9"] [calfpath "0.8.1"] - [org.clojure/core.async "1.3.610"] + [org.clojure/core.async "1.3.618"] [manifold "0.1.8"] - [funcool/promesa "6.0.0"] + [funcool/promesa "6.0.2"] [metosin/sieppari] [yada "1.2.16"] [aleph "0.4.6"] - [ring/ring-defaults "0.3.2"] + [ring/ring-defaults "0.3.3"] [ataraxy "0.4.2"] [bidi "2.1.6"] [janus "1.3.2"]]} diff --git a/test/cljc/reitit/ring_coercion_test.cljc b/test/cljc/reitit/ring_coercion_test.cljc index 3e38029e..06b5808c 100644 --- a/test/cljc/reitit/ring_coercion_test.cljc +++ b/test/cljc/reitit/ring_coercion_test.cljc @@ -397,7 +397,7 @@ (testing "encoding errors" (let [app (->app {:encode-error (fn [error] {:errors (:humanized error)})})] (is (= {:status 400, :body {:errors {:x ["missing required key"]}}} - (app (assoc (->request "closed") :body-params {})))))) + (app (assoc (->request "closed") :body-params {})))))) (testing "when schemas are not closed and extra keys are not stripped" (let [app (->app {:compile (fn [v _] v) :strip-extra-keys false})] @@ -449,7 +449,35 @@ (testing "failed response" (let [{:keys [status body]} (app (->request [{:message "kosh"}]))] (is (= 500 status)) - (is (= :reitit.coercion/response-coercion (:type body)))))))))) + (is (= :reitit.coercion/response-coercion (:type body)))))))) + + (testing "encoding responses" + (let [->app (fn [total-schema] + (ring/ring-handler + (ring/router + ["/total" {:get {:parameters {:query [:map [:x :int]]} + :responses {200 {:body [:map [:total total-schema]]}} + :handler (fn [{{{:keys [x]} :query} :parameters}] + {:status 200 + :body {:total (* x x)}})}}] + {:data {:middleware [rrc/coerce-request-middleware + rrc/coerce-response-middleware] + :coercion malli/coercion}}))) + call (fn [accept total-schema] + ((->app total-schema) {:uri "/total" + :request-method :get + :muuntaja/request {:format "application/json"} + :muuntaja/response {:format accept} + :query-params {"x" "2"}}))] + + (testing "no encoding" + (is (= {:status 200, :body {:total +4}} (call "application/json" :int)))) + + (testing "json encoding" + (is (= {:status 200, :body {:total -4}} (call "application/json" [:int {:encode/json -}])))) + + (testing "edn encoding (nada)" + (is (= {:status 200, :body {:total +4}} (call "application/edn" [:int {:encode/json -}])))))))) #?(:clj (deftest muuntaja-test