From a4576cc62297f0aa8e728e7baa2644b7df0f1f2f Mon Sep 17 00:00:00 2001 From: ertugrulcetin Date: Fri, 29 Jan 2021 23:18:18 +0300 Subject: [PATCH 1/6] feat: support humanize options --- modules/reitit-malli/src/reitit/coercion/malli.cljc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/reitit-malli/src/reitit/coercion/malli.cljc b/modules/reitit-malli/src/reitit/coercion/malli.cljc index d8fbd663..44c35c27 100644 --- a/modules/reitit-malli/src/reitit/coercion/malli.cljc +++ b/modules/reitit-malli/src/reitit/coercion/malli.cljc @@ -128,7 +128,7 @@ ([] (create nil)) ([opts] - (let [{:keys [transformers lite compile options error-keys encode-error] :as opts} (merge default-options opts) + (let [{:keys [transformers lite compile options error-keys encode-error humanize-opts] :as opts} (merge default-options opts) show? (fn [key] (contains? error-keys key)) ;; Query-string-coercer needs to construct transfomer without strip-extra-keys so it will ;; use the transformer-provider directly. @@ -188,7 +188,8 @@ (-open-model [_ schema] schema) (-encode-error [_ error] (cond-> error - (show? :humanized) (assoc :humanized (me/humanize error {:wrap :message})) + (show? :humanized) (assoc :humanized (me/humanize error (cond-> {:wrap :message} + humanize-opts (merge humanize-opts)))) (show? :schema) (update :schema edn/write-string opts) (show? :errors) (-> (me/with-error-messages opts) (update :errors (partial map #(update % :schema edn/write-string opts)))) From ea58100fecb072f506afc934b034ed110581934f Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Fri, 14 Nov 2025 13:51:23 +0200 Subject: [PATCH 2/6] test: add test for malli coercion :humanize-opts --- test/cljc/reitit/ring_coercion_test.cljc | 30 +++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/test/cljc/reitit/ring_coercion_test.cljc b/test/cljc/reitit/ring_coercion_test.cljc index f74f65b9..14db797b 100644 --- a/test/cljc/reitit/ring_coercion_test.cljc +++ b/test/cljc/reitit/ring_coercion_test.cljc @@ -583,7 +583,35 @@ :request-method :get}))] (is (= {:status 200, :body {:total "FOO: this, BAR: that"}} (call m/schema custom-meta-merge-checking-schema))) - (is (= {:status 200, :body {:total "FOO: this, BAR: that"}} (call identity custom-meta-merge-checking-parameters))))))) + (is (= {:status 200, :body {:total "FOO: this, BAR: that"}} (call identity custom-meta-merge-checking-parameters))))) + + (testing "options" + (let [->app (fn [options] + (ring/ring-handler + (ring/router + ["/api" {:get {:parameters {:body [:map + [:i :int] + [:x :string]]} + :handler (fn [{{:keys [body]} :parameters}] + {:status 200 :body {}})}}] + {:data {:middleware [rrc/coerce-exceptions-middleware + rrc/coerce-request-middleware + rrc/coerce-response-middleware] + :coercion (malli/create options)}}))) + request {:uri "/api" + :request-method :get + :muuntaja/request {:format "application/json"}}] + (testing "humanize options" + (is (= {:i ["should be an integer"] :x ["missing required key"]} + (-> ((->app nil) (assoc request :body-params {:i "x"})) + :body + :humanized))) + (is (= {:i ["SHOULD INT"] :x ["MISSING"]} + (-> ((->app {:humanize-opts {:errors {:int {:error/message {:en "SHOULD INT"}} + :malli.core/missing-key {:error/message {:en "MISSING"}}}}}) + (assoc request :body-params {:i "x"})) + :body + :humanized)))))))) #?(:clj (deftest per-content-type-test From af7313bd9b68227ac839f6dc58c865d4eec49c04 Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Fri, 14 Nov 2025 14:05:36 +0200 Subject: [PATCH 3/6] test: add test for overriding malli registry --- test/cljc/reitit/ring_coercion_test.cljc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/cljc/reitit/ring_coercion_test.cljc b/test/cljc/reitit/ring_coercion_test.cljc index 14db797b..10fbb1f2 100644 --- a/test/cljc/reitit/ring_coercion_test.cljc +++ b/test/cljc/reitit/ring_coercion_test.cljc @@ -585,7 +585,7 @@ (is (= {:status 200, :body {:total "FOO: this, BAR: that"}} (call m/schema custom-meta-merge-checking-schema))) (is (= {:status 200, :body {:total "FOO: this, BAR: that"}} (call identity custom-meta-merge-checking-parameters))))) - (testing "options" + (testing "malli options" (let [->app (fn [options] (ring/ring-handler (ring/router @@ -593,7 +593,7 @@ [:i :int] [:x :string]]} :handler (fn [{{:keys [body]} :parameters}] - {:status 200 :body {}})}}] + {:status 200 :body body})}}] {:data {:middleware [rrc/coerce-exceptions-middleware rrc/coerce-request-middleware rrc/coerce-response-middleware] @@ -611,7 +611,12 @@ :malli.core/missing-key {:error/message {:en "MISSING"}}}}}) (assoc request :body-params {:i "x"})) :body - :humanized)))))))) + :humanized)))) + (testing "overriding registry" + (is (= {:body {:i "x" :x "x"} :status 200} + (-> ((->app {:options {:registry (merge (m/default-schemas) + {:int :string})}}) + (assoc request :body-params {:i "x" :x "x"})))))))))) #?(:clj (deftest per-content-type-test From eb06404f1ef08086d9742153fc30c71d400b3d04 Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Fri, 14 Nov 2025 14:06:43 +0200 Subject: [PATCH 4/6] feat: fold malli :humanize-opts into :options --- modules/reitit-malli/src/reitit/coercion/malli.cljc | 4 ++-- test/cljc/reitit/ring_coercion_test.cljc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/reitit-malli/src/reitit/coercion/malli.cljc b/modules/reitit-malli/src/reitit/coercion/malli.cljc index 44c35c27..2e4ab782 100644 --- a/modules/reitit-malli/src/reitit/coercion/malli.cljc +++ b/modules/reitit-malli/src/reitit/coercion/malli.cljc @@ -128,7 +128,7 @@ ([] (create nil)) ([opts] - (let [{:keys [transformers lite compile options error-keys encode-error humanize-opts] :as opts} (merge default-options opts) + (let [{:keys [transformers lite compile options error-keys encode-error] :as opts} (merge default-options opts) show? (fn [key] (contains? error-keys key)) ;; Query-string-coercer needs to construct transfomer without strip-extra-keys so it will ;; use the transformer-provider directly. @@ -189,7 +189,7 @@ (-encode-error [_ error] (cond-> error (show? :humanized) (assoc :humanized (me/humanize error (cond-> {:wrap :message} - humanize-opts (merge humanize-opts)))) + options (merge options)))) (show? :schema) (update :schema edn/write-string opts) (show? :errors) (-> (me/with-error-messages opts) (update :errors (partial map #(update % :schema edn/write-string opts)))) diff --git a/test/cljc/reitit/ring_coercion_test.cljc b/test/cljc/reitit/ring_coercion_test.cljc index 10fbb1f2..162d5c59 100644 --- a/test/cljc/reitit/ring_coercion_test.cljc +++ b/test/cljc/reitit/ring_coercion_test.cljc @@ -607,8 +607,8 @@ :body :humanized))) (is (= {:i ["SHOULD INT"] :x ["MISSING"]} - (-> ((->app {:humanize-opts {:errors {:int {:error/message {:en "SHOULD INT"}} - :malli.core/missing-key {:error/message {:en "MISSING"}}}}}) + (-> ((->app {:options {:errors {:int {:error/message {:en "SHOULD INT"}} + :malli.core/missing-key {:error/message {:en "MISSING"}}}}}) (assoc request :body-params {:i "x"})) :body :humanized)))) From 451b286f1db51676a519e75c29545ff7844de2aa Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Fri, 14 Nov 2025 14:16:48 +0200 Subject: [PATCH 5/6] doc: add brief docs for configuring humanized error messages --- doc/coercion/malli_coercion.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/coercion/malli_coercion.md b/doc/coercion/malli_coercion.md index b193db11..4b05e721 100644 --- a/doc/coercion/malli_coercion.md +++ b/doc/coercion/malli_coercion.md @@ -96,3 +96,16 @@ Using `create` with options to create the coercion instead of `coercion`: ;; malli options :options nil}) ``` + +## Configuring humanize error messages + +Malli humanized error messages can be configured using `:options :errors`: + +```clj +(reitit.coercion.malli/create + {:options + {:errors (assoc malli.error/default-errors + :malli.core/missing-key {:error/message {:en "MISSING"}})}}) +``` + +See the malli docs for more info. From 78aba57d2d4ce27299a5026fad7effbff2fa01ed Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Fri, 14 Nov 2025 14:58:52 +0200 Subject: [PATCH 6/6] doc: document configuring malli registry --- doc/coercion/malli_coercion.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/coercion/malli_coercion.md b/doc/coercion/malli_coercion.md index 4b05e721..73f751ac 100644 --- a/doc/coercion/malli_coercion.md +++ b/doc/coercion/malli_coercion.md @@ -109,3 +109,16 @@ Malli humanized error messages can be configured using `:options :errors`: ``` See the malli docs for more info. + +## Custom registry + +Malli registry can be configured conveniently via `:options :registry`: + +```clj +(require '[malli.core :as m]) + +(reitit.coercion.malli/create + {:options + {:registry {:registry (merge (m/default-schemas) + {:my-type :string})}}}) +```