miner/herbert

Reusable schema

jeluard opened this issue · 3 comments

Apologize in advance this is not an issue but a question. I wasn't sure what was the proper canal to ask it.

I'd like to create reusable schemas that I can then reference in other schemas. I could not find a way to achieve that. Is it feasible?

e.g.

(def user '{:type "user" :id int}
(def blog '{:owner user :authors [user+]})

(h/conforms? blog {:owner [{:type "user" :id 1}] :authors [{:type "user" :id 2}]}
miner commented

The grammar pattern will let you use named patterns (or "rules"). (See the README for documentation.) Something like the following examples should work for you:

(h/conforms? '(grammar blog  
                        user {:type "user" :id int}   
                        blog {:owner user :authors [user+]})   
  {:owner {:type "user" :id 1} :authors [{:type "user" :id 2}]})

(h/conforms? '(grammar {:owner user :authors [user+]}   user {:type "user" :id int})   
    {:owner {:type "user" :id 1} :authors [{:type "user" :id 2}]})

Note, there's also a h/schema-merge function that will let you combine predefined grammar patterns. The following example is a bit contrived as each grammar has only a single rule. In a more realistic case, you would use a grammar pattern to hold a number of named rules, but I hope this shows the basic idea.

(def user '(grammar user user {:type "user" :id int}))
(def blog '(grammar blog blog {:owner user :authors [user+]}))
(h/conforms? (h/schema-merge blog user)  
  {:owner {:type "user" :id 1} :authors [{:type "user" :id 2}]})
miner commented

A schema-merge example should be added to the documentation.

Thanks this is what I was looking for!