Fork me on GitHub
#malli
<
2022-11-09
>
J09:11:53

Hi guys! I have a question about how to check “extra constraints”. Let’s say, we have this schema:

(def CreatCommentPayload
 [:map
  [:comment/owner uuid?]
  [:comment/text string?]
  [:comment/associated-account [:vector uuid?]]])
For example, this payload is valid for create a comment:
(validate CreateCommentPayload {:comment/owner #uuid "92688fe4-9050-42b0-af5d-6d74a3b3d65b"
                                :comment/text "Hello"
                                :comment/associated-account [#uuid "864fbd90-914d-4c6d-b1b9-415276f7dda8"]}
In fact, this is not enough validation. There is some other possible validations: • comment/owner should exist in the database. • Each account in comment/associated-account should exist in the database. There are several ways to check this two other facts: 1- Custom schema Like:
(def CreateCommentPayload
 [:map
  [:comment/owner [:and uuid? exists?]
  [:comment/text string?]
  [:comment/associated-account [:and [:vector uuid?] exists?]])
exists? is a custom function to check if one or several accounts is or not in the database. 2- Constraint schema Like:
(def CreateCommentConstraint
 [:fn (fn [comment-payload]
        (exists? (into (:comment/associted-account comment-payload []) (:comment/owner comment-payload))
(def CreateCommentSchema
 [:and CreateCommentPayload CreateCommentConstraint])
We reuse the exists?function but here we check all the accounts with one request. 3- Don’t check constraint in schema There will be a solution. The check of this constraints can be done in another layer of the app. What’s your position about this case?

Ben Sless12:11:31

Since the constraints you specify involve side effects, I'd say they shouldn't be in the schema

👆 1
eskos13:11:52

Schema is about structural validation, while you could with eg. fn schemas make them check from db all the things, it’s probably cleaner to implement that as separate validation layer. Or rely on db constraints themselves, and handle insert/update failures gracefully.

dvingo20:11:24

Am I missing something obvious here?

(m/schema [:comment {:some :prop}] 
  {:registry (merge (m/default-schemas) {:comment :int})})
=> [:int {:some :prop}]
does not work:
(m/schema [:comment {:some :prop}] 
  {:registry (merge (m/default-schemas) {:comment [:map [:a :int]]})})
Execution error (ExceptionInfo) at malli.core/-fail! (core.cljc:138).
:malli.core/invalid-schema {:schema [:map [:a :int]]}

aaron5121:11:56

Is a :fn schema of (.exists (io/file x)) appropriate in Malli? Given that “schema is about structural validation”? (https://clojurians.slack.com/archives/CLDK6MFMK/p1667999272184759?thread_ts=1667984513.081219&amp;cid=CLDK6MFMK)