8

I have below schema definition to represent commission amount in my openapi contract.

commissionAmount:
  type: number
  minimum: -99999.99
  maximum: 99999.99

Generated Code:

@Valid
@DecimalMin("-99999.99") @DecimalMax("99999.99") 
public BigDecimal getCommissionAmount() {
  return commAmt;
}

The generated code is good and as expected. I just wanted to know are these -99999.99 and 99999.99 valid values for minimum and maximum.

The reason for asking this question is it does not check the limit in the fractional part. For example, I expect 12345.678 is invalid , 12345.67 is valid. But it marks both as valid.

I read @Digits is used to check for the digit limit of integer and fractional part. How do I tell openapi-generator-maven-plugin to annotate Digits as well?

Expected Generated Code:

@Valid
@Digits(integer = 5, fraction = 2)
@DecimalMin("-99999.99") @DecimalMax("99999.99") 
public BigDecimal getCommissionAmount() {
  return commAmt;
}
Sridhar
  • 1,832
  • 3
  • 23
  • 44

1 Answers1

9

The way to specify this in OpenAPI would be using multipleOf:

commissionAmount:
  type: number
  minimum: -99999.99
  maximum: 99999.99
  multipleOf: 0.01

However, using the OpenAPI Generator will not produce an annotation for this. The reason being is that there is no javax.validation annotation that can represent multipleOf effectively (imagine trying to express multipleOf: 0.02- @Digits would be insufficient).

However, you can create your own annotation as this user has: https://github.com/OpenAPITools/openapi-generator/issues/2192#issuecomment-575132233

With the following annotation and validator:

@Target({METHOD, FIELD})
@Retention(RUNTIME)
@Repeatable(MultipleOf.List.class)
@Constraint(validatedBy = MultipleOfValidator.class)
public @interface MultipleOf {

    double value();

    String message() default "{error.multipleOf}";

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

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

    @Target({ METHOD, FIELD })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        MultipleOf[] value();
    }

}
public class MultipleOfValidator implements ConstraintValidator<MultipleOf, Number> {

    private double value;

    @Override
    public void initialize(MultipleOf constraintAnnotation) {
        this.value = constraintAnnotation.value();
    }

    @Override
    public boolean isValid(Number value, ConstraintValidatorContext context) {
        return (value == null) || (value.doubleValue() / this.value) % 1 == 0;
    }

}

You would then be able to fork the generator and add your new annotation to the template: https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/Java/beanValidationCore.mustache

With a line like this:

{{#multipleOf}}@MultipleOf({{multipleOf}}){{/multipleOf}}
Knox
  • 1,150
  • 1
  • 14
  • 29