Skip to main content
Every rule about a property starts by deciding what null means for it. There are three answers:

required

null is a violation. Otherwise its block runs on the value.

ifPresent

null is valid. A value is checked by its block.

forbidden

Anything but null is a violation.
After required or ifPresent, the value inside the block has the non-null type: String, not String?. Every constraint works on that type, so your IDE offers only the constraints that fit it, and none of them has to think about null.
Client.kt
A company with no company name and no email breaks four rules: And a person who sends a company name breaks forbidden:

required

::email required { email() } reports is required, with the code required, when the property is null, and the block does not run, so there is never a second violation about a missing value. When the value is there, the block runs on it. To change the message of one property, call it as a function, with the message first:
To change it for every property, change messages.required.
A block can be empty: ::street required {} only checks that the street is there.

ifPresent

::nickname ifPresent { minLength(3) } accepts null, and checks the value when there is one. Use it for optional fields that still have a shape when they are filled in.

forbidden

::companyName.forbidden() reports must be null, with the code forbidden, when the property has a value. It is usually inside a condition, for a field that one kind of object must not have:
It takes a message too: ::password.forbidden("a guest has no password").

Values that are not properties

required and ifPresent also take a path and a value, for something that is not a property, such as a value computed from others or read from a map:
The path is the path of the violations, so they point at the right place.

notNull, for elements

Inside an each over a collection of nullable values, the element can still be null, and there is no property to call required on. notNull() checks it, with the message of required (is required) and the code notNull:
On a property, prefer required to notNull(): only required gives its block the non-null type.