I'm looking for a Python (<3) validation API something like Java's Bean Validation or Spring validation. I'm not looking for a library that is limited to form validation, since I want to validate domain objects.
Do you know a Python API for validating of domain objects?
maybe you should try formencode? it's not form-only validation library
Spring.py
The only libraries that are a bit like Java's Bean validation that I know (and have used) are:
Zope 3's zope.schema , but this is tied to using zope interfaces I think
SQLAlchamy's Elixir, but this is tied to using SQLAlchemy entities
I'm not sure if (or how) these could be used without depending of specific super classes
+1 for formencode and also there is promising pycerberus .
Related
Background
We are currently implementing an application using hexagonal architecture. Our REST API DTOs are mapped to our entities via MapStruct. This works fine. (Though, it would be much nicer if MapStruct would have support for hierarchical structures.)
Problem
However, we are facing a problem which is best described by the following example:
Consider you have an entity Person that stores the date of birth. Now, this
entity has a method which might be called int calculateAge().
The REST API's PersonDto will get an attribute int age.
Now, we want MapStruct to generate this mapping for us. Our approach was to try to configure #Mapping(target = "age", ...) to use the int calculateAge() method as source, but we did not succeed.
Believing this might be a straightforward application of MapStruct, we were quite disappointed to not come up with a clean solution after searching on this topic for hours.
Solutions
We found two solution approaches that work, but are (in our opinion) not really maintainable:
Use #Mapping(expression = "java(...)")
Use #AfterMapping to post process the constructed DTO and implement the required mappings in the annotated method
Question
Is there a cleaner way to achieve our goal, something which might look like this #Mapping(sourceMethod = "calculateAge", target = "age)?
Is there a cleaner way to achieve our goal, something which might look like this...
No, there isn't as of the MapStruct latest stable version (1.4.1.Final) of time of writing this answer. You have basically two choices which heavily depends what exactly and how you want to map the fields. I describe shortly in what case each solution is suitable for:
The first solution using expression introduces the problem the methods are hardcoded in the annotation. I prefer this solution only in the case of simple format conversions or calculations without calling a custom method (only from the existing Java API). Anyway, even with your proposed solution it would be still hardcoded. The syntax is the only thing that changes. There is effectively no difference in terms of maintainability:
#Mapping(target = "age", expression = "java(...)") // current API
#Mapping(sourceMethod = "calculateAge", target = "age") // hypothetical
Feel free to request for such feature. This solution in any case also requires imports within the mapper (#Mapper(imports = Another.class)) as well as the "hypothetical" one.
The annotation #AfterMapping is useful in case of more complex transformations and calculations. It's not as clean as a single annotation call and in fact you still write the mapping manually, however, it brings more control over the called methods which the IDE highlights before the compilation (at least you don't need an additional IDE-specific plugin). I'd go for this solution in case I need to call my custom methods and logics.
From what I've seen, Mapstruct relies on standard getters and setters. If you want to use a specific method then Mapstruct does work with #qualifiers, but I don't think the method can be in the entity. From my experience the best solution is to use #AfterMapping, as you mentioned.
I am using bean-validation with apache bval as its implementation. (I do not want to use hibernate-validation or oval, because they have too much dependencies.)
First question: Is bval still maintained or is it orphaned?
Second question: Is it possible to implement custom validators using bval? E.g. a need a validator to File field that validates, that the file exists, isreadable and a file.
Apache BVal is afaik compliant with Bean Validation 1.0 which means should be able to write portable custom constraints. However, BVal is not yet Bean Validation 1.1 compatible, meaning you won't have executable constraints.
I don't know how active development is atm. Last release was in September 2012 which is quite a while back.
What is your concern with the Hibernate Validator or OVal dependencies?
Somebody did a performance comparison. However I am not sure how objective this comparison is: http://soularis999.blogspot.com/2011/07/bean-validation-performance-evaluation.html
Theres a how to now on baeldung.com: https://www.baeldung.com/apache-bval, it looks pretty standard
define an new annotation describing your constraint
define an constraint validator which implements ConstraintValidator<CONSTRAINT, TARGET>
annotatate your annotation with #Constraint(validatedBy={Validator.class})
Before I was using Python NDB API and there was required attribute which I can set on properties. I can't find anything similar in Objectify documentation. How to do that with Objectify?
You may want to use the standard java bean validation framework for this:
http://beanvalidation.org/
It seems that objectify has no such functionality, where you would require user to set a value of field.
You can however prevent saving of fields with null value: #IgnoreSave(IfNull.class). (you can use any of the [If][2] subclasses: IfDefault, IfEmpty, IfEmptyString, IfFalse, etc..)
I need to take all the fields and collections from Bean1 and Bean2, sometimes apply some business logic, and produce Bean3 (all beans are hibernate/domain objects of the same type with a reasonably complex graph).
Any thoughts on how to do this? Done something similar in the past?
My ideas:
Dozer (http://dozer.sourceforge.net/)
BeanUtils (http://commons.apache.org/beanutils/)
Handrolled solution
A.N.Other cool solution?
Any recommendations?
Dozer is a nice bean mapping tool.
However, it won't perform any business logic, of course.
I should not be a problem to implement a business logic and to rely on Dozer for bean mapping. This is what I would do.
Neither of the tools provides business logic - also it has to be implemented somehow. Bean utils are goot to access bean properties with standard notation. You may try groovy to implement business logic with nice syntax.
Are there any commonly usable annotations available? Similar to commons-lang?
If not, have you seen any effective use of annontations (not built-in annotations) as part of any open source application development.
I remember Mifos was using it for Transaction.
Mohan
i think Hibernate Validator has really good and reusable annotations for any kind of validation. it is based on a the reference implementation for JSR 303: Bean Validation.
Only non-standard annotations I've used more than once outside my testing project have been WicketStuff Annotations which are very useful in their own context.
Another interesting annotation set which is also the basis for JSR-305 is FindBugs' annotations which also may prove useful in the future - we'll see how that goes.
Check out my Bean annotations
http://code.google.com/p/javadude/wiki/Annotations
Things like
#Bean(
cloneable=true,
defineSimpleEqualsAndHashCode=true,
properties={
#Property(name="name", bound=true),
#Property(name="age", type=int.class, bound=true),
#Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
},
observers={
#Observer(type=FeverListener.class)
}
)
public class Person extends PersonGen { }
The annotation processor generates the PersonGen superclass.
Note that I'm currently working on a major change to them and the API is changing (I'll still leave the current version available, but the 3.x.x version stream will be breaking)
I'm trying to get the new version done in the next couple of weeks.
JAXB defines annotations (javax.xml.bind.annotation) that are reused to some degree -- although they are named to indicate they only related to XML serialization, most of metadata has to do with annotating properties to serialize, so they can be used for serializing to other data formats (such as JSON) too. Jackson JSON processor supports them, along its own 'native' annotations, since there are no really standardizes non-data-format specific annotations (AFAIK).
I like and Oval http://oval.sourceforge.net/ and JAXB
there really needs to be a set of common annotationsin the core jre which are used in similar ways in multiple frameworks.
for example #Transactional #Nullable