Search code examples
clojureschemamalli

How to wrap one schema inside another for Malli?


This is my payload.

(m/validate readingDetails-schema 
{:readingCode : "Code1",
  :readingNumber : "twenty two round off",
  :readingCheck : "First",
  :readings : [{
    :readingDate : "2021-05-02",
    :readingType : "first check",
    :readingPrecision : "two decimals check",
    :readingEstimate : "Check"}]})
 

This is my first schema:

(def reading-schema (m/schema            [:map
                                          [:readingDate :re #"\d{4}-\d{2}-\d{2}"]
                                          [:readingType string?]
                                          [:readingPrecision decimal?]
                                          [:readingEstimate string?]]))
=> #'interest-malli-test.core/reading-schema

Now this is the main schema, which must include the above schema.

(def readingDetails-schema                  [:merge
                                               #ref [:reading-schema]
                                               [:map
                                                [:readingCode string?]
                                                [:readingNumber string?]
                                                [:readingCheck string?]
                                                [<how to add a list of reading-schema here?>]
                                                ]])

I'm trying like this.

(def readingDetails-schema                  [:merge
                                                   #ref [:reading-schema]
                                                   [:map
                                                    [:readingCode string?]
                                                    [:readingNumber string?]
                                                    [:readingCheck string?]
                                                    [[:vector #ref [:reading-schema]]
                                                    ]])

Solution

  • After you convert the payload into Clojure data structures, just use the name of the first schema in the second one (and change decimal? into string?).

    Dependencies: [metosin/malli "0.8.9"]

    Require: [malli.core :as m]

    (def reading-schema
      [:map
       [:readingDate :re #"\d{4}-\d{2}-\d{2}"]
       [:readingType string?]
       [:readingPrecision string?]
       [:readingEstimate string?]])
    
    (def readingDetails-schema
      [:map
       [:readingCode string?]
       [:readingNumber string?]
       [:readingCheck string?]
       [:readings [:vector reading-schema]]])
    
    (m/validate readingDetails-schema
                {:readingCode   "Code1",
                 :readingNumber "twenty two round off",
                 :readingCheck  "First",
                 :readings      [{:readingDate      "2021-05-02",
                                  :readingType      "first check",
                                  :readingPrecision "two decimals check",
                                  :readingEstimate  "Check"}]})
    
    => true