Anyone dealt with coercion on multi malli schema where the dispatch value is supposed to be coerced into a keyword? I'm trying to keep my schema serializable (i.e. no function defintions). E.g. I'm getting a invalid dispatch value here:
(require '[malli.core :as malli]
'[malli.transform :as malli-transform])
(malli/coerce [:multi {:dispatch :type}
[:a [:map [:type [:enum :a]]]]
[:b [:map [:type [:enum :b]]]]]
{:type "a"}
(malli-transform/transformer
malli-transform/string-transformer))
I could explicitly update the value to keyword but that'll require an explicit middleware for my server which would probably be too explicit.
Any ideas on how to circumvent this?IIRC :decode/string from :multi schema level would be applied before multi dispatch
[:multi {:decode/string (fn [s] (keyword s)) :dispatch ...} ...]
Or maybe something like
[:and [:map [:type :keyword]] [:multi ...]] so Malli knows before selecting the multi schema that the type property has to be coerced
Usually :decode/string is the correct choice to apply per-property coercion where the property requires special coercion or the coercion needs to be done before Malli knows the "real" schema for the property (like with :multi)
Yeah dispatching with a fn would work but it won't be serializable anymore. I'll just use strings
The :and might work
Such simple fns could be evaluated with Sci: https://github.com/metosin/malli?tab=readme-ov-file#persisting-schemas
but it is an additional dependency
And hm, https://github.com/metosin/malli?tab=readme-ov-file#serializable-functions, these example are for :fn schema functions, not sure if fns in schema properties, like :decode/string work the same
But :and version is likely the most "schema as data" approach for this
Thanks! I'll try out the :and approach and see if that helps
(require '[malli.core :as malli]
'[malli.transform :as malli-transform])
(malli/coerce [:and [:map [:type :keyword]] [:multi {:dispatch :type}
[:a [:map [:type [:enum :a]]]]
[:b [:map [:type [:enum :b]]]]]]
{:type "a"}
(malli-transform/transformer
malli-transform/string-transformer))
Worksit’s probably not “the way” but you can hack it by making the dispatch function turn strings into keywords with (comp keyword :type).