1

I am using the Spring Boot framework to create a RESTFUL API and I need a way to avoid the duplication of validation rules when using multiple DTOs as request/response objects for my endpoints.

Using the following example for the Entity

@Entity
public class Post
{
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @NotNull @NotBlank @Length(min = 3, max = 21)
    private String name;

    @Length(max = 128)
    private String description;
    
}

and the DTO

public class CreatePostDTO
{
    @NotNull @NotBlank @Length(min = 3, max = 21)
    private String name;
    
    @Length(max = 128)
    private String description;
}

How can one avoid writing the validation rules for each DTO created? I have considered implementing common interfaces but that would only work well if the entities and DTOs share most if not all fields.

1
  • I see one vote to close because this question is asking for assistance with writing code, but I disagree with that reason. This is a software design problem. The solution will likely require code, but this is not a "fix my bug" kind of question. Commented Mar 26 at 14:37

3 Answers 3

2

The problem here is that annotations tightly couple your class to some package, NHibernate? and Whatever validation package you are using.

Ideally you would have a clean POJO class for your business object and keep the validation and data layer stuff separate.

Then you could reuse your validation logic, or decide that you only need to validate on a single layer and save youself lots of duplicated PostOfSomeKind objects

1

A potential solution would be declaring a new annotation type for each shared field and decorating it with the validation rules.

@NotNull @NotBlank @Length(min = 3, max = 21)
@Documented
@Constraint(validatedBy = {})
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PostNameValidation
{
    String message() default "Not a valid Post name";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

As a result, each field that corresponds to the Post name in an Entity or DTO can be annotated with @PostNameValidation, removing the need to write duplicate validation rules.

1

According to spring framework documentation, section Java Bean Validation:

The Spring Framework provides support for the Java Bean Validation API.

 

How can one avoid writing the validation rules for each DTO created?

For each bean to be validated develop a corresponding validator by implementing the Validator interface, included in the Spring library in use, and for the common validations develop a class and in each validator requiring common validations add a field of type of the common validations class.

All that although I have the feeling this question is more appropriate for SO community.

Not the answer you're looking for? Browse other questions tagged or ask your own question.