mirror of
https://github.com/metosin/reitit.git
synced 2026-02-18 16:55:55 +00:00
I suspected the malli coercion custom registry example was broken, so I wanted to get it tested and the coercion Malli options indeed had an extra layer of map.
3.9 KiB
3.9 KiB
Malli Coercion
Malli is data-driven Schema library for Clojure/Script.
Default Syntax
By default, Vector Syntax is used:
(require '[reitit.coercion.malli])
(require '[reitit.coercion :as coercion])
(require '[reitit.core :as r])
(def router
(r/router
["/:company/users/:user-id" {:name :user/user-view
:coercion reitit.coercion.malli/coercion
:parameters {:path [:map
[:company string?]
[:user-id int?]]}}]
{:compile coercion/compile-request-coercers}))
(defn match-by-path-and-coerce! [path]
(if-let [match (r/match-by-path router path)]
(assoc match :parameters (coercion/coerce! match))))
Successful coercion:
(-> (into {} (match-by-path-and-coerce! "/metosin/users/123"))
(dissoc :result :data))
;; => {:template "/:company/users/:user-id",
;; :path-params {:company "metosin", :user-id "123"},
;; :parameters {:path {:company "metosin", :user-id 123}}
;; :path "/metosin/users/123"}
Failing coercion:
(try
(match-by-path-and-coerce! "/metosin/users/ikitommi")
(catch clojure.lang.ExceptionInfo e (.getMessage e)))
;; => "Request coercion failed"
Lite Syntax
Same using Lite Syntax:
(def router
(r/router
["/:company/users/:user-id" {:name ::user-view
:coercion reitit.coercion.malli/coercion
:parameters {:path {:company string?
:user-id int?}}}]
{:compile coercion/compile-request-coercers}))
Configuring coercion
Using create with options to create the coercion instead of coercion:
(require '[malli.util :as mu])
(reitit.coercion.malli/create
{:transformers {:body {:default reitit.coercion.malli/default-transformer-provider
:formats {"application/json" reitit.coercion.malli/json-transformer-provider}}
:string {:default reitit.coercion.malli/string-transformer-provider}
:response {:default reitit.coercion.malli/default-transformer-provider
:formats {"application/json" reitit.coercion.malli/json-transformer-provider}}}
;; set of keys to include in error messages
:error-keys #{:type :coercion :in #_:schema :value #_:errors :humanized #_:transformed}
;; support lite syntax?
:lite true
;; schema identity function (default: close all map schemas)
:compile mu/closed-schema
;; validate request & response
:validate true
;; top-level short-circuit to disable request & response coercion
:enabled true
;; strip-extra-keys (affects only predefined transformers)
:strip-extra-keys true
;; add/set default values
;; Can be false, true or a map of options to pass to malli.transform/default-value-transformer,
;; for example {:malli.transform/add-optional-keys true}
:default-values true
;; encode-error
:encode-error nil
;; malli options
:options nil})
Configuring humanize error messages
Malli humanized error messages can be configured using :options :errors:
(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.
Custom registry
Malli registry can be configured conveniently via :options :registry:
(require '[malli.core :as m])
(def coercion
(reitit.coercion.malli/create
{:options
{:registry (merge (m/default-schemas)
{:my-type :int})}}))
(def coercer (reitit.coercion/-request-coercer coercion :string [:map [:x :my-type]]))
(coercer {:x "5"} :default)
=> {:x 5}