I’m documenting for myself what I would look for in a validation library. The code I currently need it for is in Kotlin so I have the entire JVM ecosystem to choose from.
Certainly well battle tested but I dislike the annotations approach; while nice for simple validations it can get hairy when testing real scenarios: inter-dependent objects, database access and external services all need to be wired in somehow and I really don’t want to get to the point where I am solving problems of my library rather than my own.
… too many battle scars …
Also, working with jOOQ’s Record
I don’t really have domain objects to easily annotate.
And of course the library is extremely Javaesque - the first step of a tutorial begins with creating your very own ValidatorFactory: Validation.buildDefaultValidatorFactory()
-
I’m in the mood for something lighter.
There are a few functional approaches for the Java ecosystem out there that either abuse Java’s Stream
or start
gushing about monads in paragraph 2 of the docs and neither of those are very appealing to me.
Looks interesting, but is light on documentation which is really not good. Also poor commit discipline.
All validation libraries seem to get readability, at least when it comes to the simple cases.
The JSRs allow you to annotate things like @NotNull @Size(min=1, max=16)
and the functional examples use lambdas.
Flexibility is not a given anymore - annotations have a hard time seeing related objects unless they are in the same object hierarchy.
In Kotlin, functions seem like the perfect candidates; we can reuse the general ones in and easily write more specific tests, inline if more convenient.
Easily selecting which properties should be validated, if we don’t need them all (while keeping code DRY), seems trickier but doable.
But what should the functions return?
A Validation object? Exceptions?
Should they be a part of a larger Validation objects and modify its state or should they be purer and simply return some sort of ValidationError
objects when something goes wrong?
We need to provide feedback to the user - what went wrong?
We need to list the errors, translated, and know which errors belongs to which specific properties of the object under validation, and which are general errors (and we also need a convenient way to detect and identify these errors programatically).
It would be good to be able to see the original object, perhaps as it currently exists in the database. It would be good to be able to get the new value of a property as it will get stored in the database when the user solves the validation issues.
Various severity levels of the errors would also be good - sometimes we would just like to warn the user, e.g. when a password is too simple.
Making it easy to build UI renderers for the errors and plug them into whatever I am using would obviously be nice.
Grouping validations would be great so the same group of tests can be applied to multiple entities (preferrably with gracefull fallbacks when a validation step cannot be used) - but not at the expense of type safety - union types would be very handy here.
Validation read in from somewhere (config files, databases..) would be a nice feature as well, either full-blown or simply to turn some validations on/off.