Validation
The API generated with the rest-expanders
comes with (optional) validation features. This includes several validation mechanisms, grouped into two categories:
- Input validation is validation that currently happens solely in the
CONTROL
layer. This validation only happens for endpoints that take input payloads (POST
,PUT
andPATCH
). - Database validation is validation that requires database access, such as checkin whether something already exists in the system.
These validations are implemented and executed in the
LOGIC
layer, but can also be called through a pipeline from theCONTROL
layer. This is typically for URL validation, to verify that a requested resource exists.
Component
This option will enable the generation of validation infrastructure in the REST JAX-RS API.
Almost all projects will want to use this option in combination with enableJaxrs
.
<options>
<enableValidation/>
</options>
Default validations
Required fields
Field
The option isRequired
is an option introduced by the main expanders.
If this option is added to a Field, this field should never be empty.
When the option exposeRestField
is present, this option will add additional code to the input validation of the JAX-RS REST endpoints.
<options>
<isRequired/>
</options>
The REST expanders can generate validation for required fields when they are exposed with exposeRestField
and have the option isRequired
.
private void validateInput(MyElementPostInputModel inputModel) {
InputValidation validation = InputValidation.init(inputModel, "jsonInput")
.isRequired();
errors.addAll(validation.getErrors());
if (validation.hasNoErrors()) {
validateName(inputModel);
// @anchor:validateInput:start
// @anchor:validateInput:end
// anchor:custom-validateInput:start
// anchor:custom-validateInput:end
}
}
private void validateName(MyElementPostInputModel inputModel) {
InputValidation validation = InputValidation.init(inputModel.getName(), "name")
.isRequired()
.isString()
// @anchor:validate-office:start
// @anchor:validate-office:end
// anchor:custom-validate-office:start
// anchor:custom-validate-office:end
;
errors.addAll(validation.getErrors());
}
Aside from the input validation itself, a unit test will also be generated to verify that the input validation works correctly. Though with being generated, this does not necessarily add a lot of value to the project, but it does increase code coverage significantly.
@Test
public void successNameIsRequired() {
model.setName("name");
final ValidationResult result = validator.validate(model);
assertThat(result.getErrors("name"),
not(hasItem(validationError(MISSING_REQUIRED_VALUE))));
}
Uniqueness
Field
This option can be added to a field to indicate that it should be unique. The option is introduced by the REST expanders and only supported in the JAX-RS stack.
When the option exposeRestField
is present, this option will add additional code to the database validation of the JAX-RS REST endpoints.
<options>
<isUnique/>
</options>
The REST expanders provide a method to check for uniqueness of individual fields
(predating unique constraints) by
adding the option isUnique
to the field.
Implied uniqueness
It is not recommended to rely on implied uniqueness. Ideally explicitly define the option isUnique
in the model to indicate that the field is assumed to be always unique.
The option generateUuid
is part of the functionality of Expanders. When added to a field, this option ensures that a new UUID will be generated for that field in the Cruds.create()
method whenever a new instance of the DataElement is created. The REST expanders assume that the option isUnique
is implicit when this option is added to a field, as it ensures that a unique UUID is always generated. In that case, all properties of the isUnique
option will also apply to the field.
The value if_empty
changes the behavior of the option generateUuid
. When this value is added, a UUID is only generated when no value is given for that field when calling the Cruds.create()
method. This implies that a UUID (or another value) can be supplied rather than generates and as such the property of this value always being unique can no longer be guaranteed, as generateUuid
by itself does not validate uniqueness. When this is the case, the REST expanders no longer assume that isUnique
is implied and it must be added explicitly if the field is used as the functionalKey
, which must always be unique for the REST API to function correctly. The REST expanders will generate a data validation to verify that the value supplied for the field in the POST
endpoint is effectively unique. The field can be exposed through the POST
endpoint, but only through PUT
and PATCH
if it is not the functionalKey
, as then it is used to uniquely identify the resource and should not be altered afterwards.