So we have a RESTful webservice that implements CRUD operations for a model, like this one:
class MyModel {
private long id;
private String name;
// other fields
private boolean completed;
private boolean active;
// getter and setters
}
In this webservice there is also a path like /service/{id}/complete
that updates just the field completed
to true. This indicates a final step for the creation.
The save and the complete operation are pretty simple and similar (they both end up calling a saveOrUpdate
). Where they differ is the validation. The complete validation is stricter.
The one before me declared an interface:
interface Validator<T> {
void validate(T t);
}
And then to check that all mandatory fields where there before setting the complete
attribute to true
we have something like (writing in pseudocode):
MandatoryFieldsValidator implements Validator<MyModel> {
list = {'id', 'active'}
public void validate(MyModel model) {
foreach(element in list) {
if(myModel.get(element) is null) throw ValidationException(element + " is mandatory");
}
}
}
So then I needed another type of validator and started doing something like this because I needed specific controls over the name
field:
NameValidator implements Validator<MyModel> {
public void validate(MyModel model) {
if(model.name is null or empty)
throw ValidationException(element + " is mandatory");
if(model.name.startswith("something"))
throw ValidationException("something not valid prefix");
if(model.name.length > 10)
throw ValidationException("too long");
}
}
The controller had an attribute of type Validator that instantiated a MandatoryFieldsValidator
so I added another attribute of the same type instantiating a NameValidator
.
Now what I don't like about this:
- The fact that I need to add a new attribute to the class as soon as I have a new validator to use;
- The fact that I'm repeating checks in different validators because even if
name
is not included in theMandatoryFieldValidator
I'm applying the same logic insideNameValidator
(is null or empty); - I will also add a new type of model and a
MandatoryFieldValidator<NewModel>
with the same type of control logic is a non-sense.
Can you give me some advice? I'm looking into a general pattern to organize this kind of validation but I'm using Java so if you have some Java specific solution is ok.