-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multi schema not working with transformers #246
Comments
The or you could add a (m/decode
[:multi {:dispatch :type
:decode/before '#(update % :type keyword)}
[:sized [:map [:type [:= :sized]] [:size int?]]]
[:human [:map [:type [:= :human]] [:name string?] [:address [:map [:country keyword?]]]]]]
{"type" "human"
:name "Tiina"
:size "98"
:address {:country "finland"
:street "this is an extra key"}}
(mt/transformer
{:name :before}
(mt/key-transformer {:decode (comp keyword str/kebab)
:encode str/camel})
mt/strip-extra-keys-transformer
mt/string-transformer)) Not on computer, so didn't check if that works. |
It didn't seem to have worked ( I'm trying to use malli to coerce API responses from JSON to Clojure data structures. Idiomatic Clojure maps use keywords as keys, hence the key transformer doing This all works well enough with simple The issue as I see it, is that the Dispatching on a string is something that works: (m/decode
[:multi {:dispatch #(get % "type")
:decode/string '#(update % "type" keyword)}
[:sized [:map [:type [:= :sized]] [:size int?]]]
[:human [:map [:type [:= :human]] [:name string?] [:address [:map [:country keyword?]]]]]]
{"type" "human"
"name" "Tiina"
"size" "98"
"address" {"country" "finland"
"street" "this is an extra key"}}
(mt/transformer
(mt/key-transformer {:decode (comp keyword str/kebab)
:encode str/camel})
mt/strip-extra-keys-transformer
mt/string-transformer)) but this means the schema needs to be aware of what the type of input keys is – I think it's better that schema would always deal with keyword keys and the transformer would apply any key coercion (if needed) to maintain the separation of concerns. Hopefully that is a clearer explanation what my issue and you can see what needs to be addressed here, either implementation- or documentation-wise. Thanks for the help! |
Ok, had time to investigate:
the example being: (require '[malli.core :as m])
(require '[malli.transform :as mt])
(require '[clojure.string :as str])
(def ->keyword (comp keyword str/lower-case m/-keyword->string))
(m/decode
[:multi {:dispatch :type
:decode/string #(update % :type ->keyword)}
[:sized [:map [:type [:= :sized]] [:size int?]]]
[:human [:map [:type [:= :human]] [:name string?] [:address [:map [:country keyword?]]]]]]
{"Type" "human"
:Name "Tiina"
:sizE "98"
:Address {:country "finland"
:street "this is an extra key"}}
(mt/transformer
;; step1: transform ALL map keys, regardless of related schema
{:default-decoder (mt/-transform-map-keys ->keyword)}
;; step2: string->edn, including the property-override in :multi
mt/string-transformer
;; step3: effects just :map s, but we are in the right branch of :multi, so it works
mt/strip-extra-keys-transformer))
;{:type :human
; :name "Tiina"
; :address {:country :finland}} |
The current code (both decoding & encoding just for malli/src/malli/transform.cljc Lines 374 to 375 in bb3e6df
|
Thanks for the example, it works as advertised! While I think it's certainly useful to showcase how this can be solved with the As such, I think changing implementation to make the behaviour more uniform and less surprising would be good (maybe with some kind of an escape hatch, like you suggest) – I'll leave the issue open for you to decide what action you prefer. |
options 1: use
|
Sorry for missing the reply, just want to say I appreciate you resolving this! I would've preferred the default to be all the types, but I understand it's for backward-compatibility and that #264 will solve it anyway. Thanks again! |
I would have expected the following code (taken from the readme and modified to add a string-to-keyword key transformer) to work - the transformer works correctly with a
:map
schema – but it doesn't:Am I doing something wrong or is this a bug?
The text was updated successfully, but these errors were encountered: