mirror of
https://github.com/metosin/reitit.git
synced 2025-12-16 16:01:11 +00:00
Fix Malli encoding,, #498
This commit is contained in:
parent
33afa9f999
commit
20b7cabed7
2 changed files with 59 additions and 14 deletions
|
|
@ -34,7 +34,7 @@
|
|||
(def json-transformer-provider (-provider (mt/json-transformer)))
|
||||
(def default-transformer-provider (-provider nil))
|
||||
|
||||
(defn- -coercer [schema type transformers f encoder {:keys [validate enabled options]}]
|
||||
(defn- -coercer [schema type transformers f {:keys [validate enabled options]}]
|
||||
(if schema
|
||||
(let [->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))
|
||||
|
|
|
|||
|
|
@ -207,6 +207,24 @@
|
|||
(let [{:keys [status]} (app invalid-request2)]
|
||||
(is (= 500 status))))))))
|
||||
|
||||
(let [app (ring/ring-handler
|
||||
(ring/router
|
||||
["/plus" {:get {:parameters {:query [:map [:x :int]]}
|
||||
:responses {200 {:body [:map
|
||||
[:total [:int {:encode/json str
|
||||
:min 0}]]]}}
|
||||
: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}}))]
|
||||
(app {:uri "/plus"
|
||||
:request-method :get
|
||||
:muuntaja/request {:format "application/json"}
|
||||
:muuntaja/response {:format "application/json"}
|
||||
:query-params {"x" "2"}}))
|
||||
|
||||
(deftest malli-coercion-test
|
||||
(let [create (fn [middleware]
|
||||
(ring/ring-handler
|
||||
|
|
@ -397,7 +415,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 +467,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
|
||||
|
|
|
|||
Loading…
Reference in a new issue