Violation with three things:
A path
Where the value is:
email, shipping.zipCode, items[1].quantity, prices[USD].A message
For people:
must be a valid email. Configurable, and translatable.A code
For programs:
email. Stable across versions and languages.The problem it solves
Most validation code starts as a fewifs in a controller. Then the rules multiply: a field required only for
companies, a total that must match its items, a coupon that must exist in the database, a message in Portuguese for
some users. The ifs spread, they stop at the first error, and nobody can tell which rules a request really follows.
Validity gives those rules one place and one vocabulary:
- Rules read like the requirements.
::email required { email() }is the sentence from the ticket. - Conditions are plain Kotlin. “Required if”, “only for companies” and “after the check-in” are an
if, awhenand a field of the object. No validation groups, no annotations on the class. nullis decided once.required,ifPresentandforbiddensettle whatnullmeans, and every constraint after them works on the non-null type.- Every error at once. A form shows all its errors in one round trip, and an API returns all of them in one response.
How it compares
Each of them is a solid choice, and some go where Validity does not yet: Konform and Akkurate run on Kotlin
Multiplatform, and Jakarta Validation plugs straight into the frameworks that read its annotations.
The ideas behind these docs
1
A validation is a list of rules about one object
You declare it in the class with
Validatable, or beside it with
validation<T> { }. Both run the same engine and accept the same constraints.2
A property starts with what null means
required, ifPresent or forbidden come first. Inside their block, the value is never
null.3
Constraints are functions on the value
email(), minLength(3), cpf(): there are 175 of them, and
your own look exactly the same.4
Validating returns every violation
validate() gives you a list. validateOrThrow() throws it, for the
edge of your system.Nothing hidden
No annotations, no code generation, nokotlin-reflect. validity-core depends on nothing but the Kotlin standard
library and kotlinx.coroutines, and phone numbers live in their own module, validity-phone,
so libphonenumber is there only if you ask for it.
Install it
Add one dependency to Gradle or Maven.
Validate your first class
From zero to a list of violations in five minutes.