Fork me on GitHub
#malli
<
2020-04-04
>
dcj01:04:52

So when I create a registry, and use it with m/schema, does that registry get saved with the schema (in -options)?

dcj03:04:14

WRT:

What is the meaning/use of the :name key in the mt/transformer input map?
Is it the case that executing mt/transformer {:name :foo :decode ... :encode...} registers that transformer via the key :foo somewhere, and it can be retrieved via mt/transformer {:name :foo}) ?

dcj03:04:14

Does a transformer that uses {:compile have to be defined inline within a specific schema, or can it be a "general" transformer that gets called against any schema ? The README example shows `

{:compile '(fn [schema _]
What is the second arg to that function (ignored here) ?

ikitommi06:04:26

:name in transformer is used for property-based transformation, I think only unqualified work right now (could be changed to support qualified too), having a transformer named :postgres allows one to define :encode/postgres and :decode/postgres keys in schema properties • currently no other used built-in keys than :registry in options, you can add you own - options are passed in mostly all user-defined callback functions. You should namespace your own option keys, just like custom schema property values, to avoid clashes • Schemas should save the options they were created with. I believe all in-built schemas do that. • :compile - it’s a feature of the interceptor, so can be used for general stuff, see the default-transformer (adding default values to schemas if missing): https://github.com/metosin/malli/blob/master/src/malli/transform.cljc#L315-L341 • second arg is the options

ikitommi06:04:46

I would like to see to options be One place to customize how malli works: defining the registry, adding error messages & localizations (https://github.com/metosin/malli/blob/master/src/malli/error.cljc#L5-L55), generarators etc, whether to use serializable functions or not (sci adds some to the bundle size in cljs) etc.

ikitommi06:04:54

having a malli schema to define the core malli options would also give good errors on invalid options 😉

ikitommi06:04:35

@dcj here’s the line: only non-qualified transformer names are supported right now https://github.com/metosin/malli/blob/master/src/malli/transform.cljc#L60. Issue & PR welcome if you want qualified too.

ikitommi06:04:19

can you ask for the entries: (satisfies? malli.core/MapSchema schema)

ikitommi06:04:00

looking at the source:

(defn map-entries
  "Returns a sequence of 3-element map-entry tuples of type `key ?properties schema`"
  ([?schema]
   (map-entries ?schema nil))
  ([?schema options]
   (if-let [schema (schema ?schema options)]
     (if (satisfies? MapSchema schema)
       (-map-entries schema)))))

ikitommi06:04:12

so, return nil or entries.

dcj06:04:32

@ikitommi no current need for qualified transformer names. Thank you again for all these answers. I will need to experiment/study transformers more tomorrow...

dcj06:04:11

@ikitommi Can :decode/foo keys in schema props be on the props for a single key in map, or only at the top :map level?

ikitommi06:04:45

all schemas, but not currently the map-entries, later, see https://github.com/metosin/malli/issues/86

ikitommi06:04:25

but this works:

[:map
 [:x [int? {:decode/postgre ...}]]]

ikitommi07:04:47

the parent-child thing (and support for recursive schemas) is the last big thing to resolve before a release. Ideas welcome on that.

pithyless12:04:33

What kind of naming conventions have people found useful for malli-specs? In clojure.spec, one has a separate registry of names (s/def ::user) but malli just uses existing ns vars. Some idioms I've seen: user-schema, User, ns.just.specs/user ; a plain (def user) I'm afraid will clash too frequently with other/local bindings in your domain.

dcj16:04:18

@pithyless Never having used malli 'in anger', my plan is to create a new/separate project/repo definitions to hold schemas and the like for a collection of interrelated projects. There will be subdirectories within definitions for specific domains, each with its own schema file/ns. So: definitions.foo.schema Within each schema file/ns I will just def the indvidual schemas, eg (def measurement (m/schema ...) I'll require these as needed like this: [definitions.foo.schema :as foo.schema] So then I'll access as foo.schema/measurement Disclaimer: Currently re-writing some code using my third schema tool, third database access library, and third time library, so clearly I can't get anything right the first N times 🙂

dcj19:04:33

I'm having trouble groking property-based transformation. Here is a simplified example:

(def my-schema
  (m/schema
   [:map {:closed true
          :encode/postgres csk/->kebab-case-keyword
          :decode/postgres csk/->snake_case_keyword}
    [:id             {:optional true
                      :postgres/type :bigserial
                      :postgres/key  :primary} int?]
    [:instrument-id  {:postgres/type :bigint
                      :postgres/null? false} int?]
    ]
   ))

(def sample
  {:id 12345
   :instrument-id 67890})

(m/decode my-schema sample (mt/key-transformer {:name :postgres}))

;; {:id 12345, :instrument-id 67890}
I was expecting the :instrument-id key to be transformed to :instrument_id I have tried quoting the values of :encode/postgres and :decode/postgres various ways both single-quote and hash-single-quite to no avail. Also tried to use mt/transformer different problems. How should I do this?

dcj20:04:12

I guess my example above is confused about the encode/decode directions/terminology, be that as it may, I still can't seem to get the key-transformers to run, no matter what....