Simple validation annotations that don't rely on Jakarta Bean Validation
Use case
In Quarkus we use Smallrye Config and @ConfigMapping for framework configuration.
This works great, but in that context we can't require additional dependencies (such as Jakarta Bean Validation and implementation), since that would force every single Quarkus application to depend on that.
Feature
It would be nice to provide some very simple validation annotations for such situation. We don't need a full-blown validation framework, just some simple validations: ranges for comparables types (integers, ...), maybe patterns for some edge cases (though those could be handled with a custom converter).
Implementation idea
The backing converter wrappers are already available in Smallrye Config:
https://github.com/smallrye/smallrye-config/blob/b0843007293067fbc90a8382b60700262a2a0d78/implementation/src/main/java/io/smallrye/config/Converters.java#L410-L624
One possibility would be to provide annotations such as these:
public @interface WithMin {
String value();
// Maybe... Jakarta Validation itself doesn't provide the option,
// so we could just assume everything is inclusive too.
boolean inclusive default true;
// Defaults to natural order for types implementing Comparable,
// but might require customization for other types?
Class<? extends Comparator<?>> comparator() default ComparableComparator.class;
}
public @interface WithMax {
String value();
boolean inclusive() default true;
Class<? extends Comparator<?>> comparator() default ComparableComparator.class;
}
public @interface WithRange {
String min();
boolean minInclusive() default true;
String max();
boolean maxInclusive() default true;
Class<? extends Comparator<?>> comparator() default ComparableComparator.class;
}
// Maybe... like I mentioned above, this would be much less useful
public @interface WithPattern {
String regexp();
}
An important feature of this proposal, and an important limitation of using the BV annotations, is that by giving our min/max values as a string, we can apply the same converter to the min/max values to ensure that we support any min/max values.
+1 to allowing a custom comparator for the comparison, +1 to this proposal overall.
The annotations should apply at the same scope as the @WithConverter to appropriately decorate it, so for example I could have a property like:
List<@WithConverter(MyHexConverter.class) @WithMin("0x01") Integer> myPositiveIntegerList();