Kotlin validation data class parameters

If I model my value objects using Kotlin data classes, then which method is best for validation. The init block seems to be the only logical place since it executes after the main constructor.

data class EmailAddress(val address: String) {

    init {
        if (address.isEmpty() || !address.matches(Regex("^[a-zA-Z0-9]+@[a-zA-Z0-9]+(.[a-zA-Z]{2,})$"))) {
            throw IllegalArgumentException("${address} is not a valid email address")
        }
    }
}

Using the JSR-303 Example

The disadvantage of this is that you need to weave boot time

@Configurable
data class EmailAddress(@Email val address: String) {

    @Autowired
    lateinit var validator: Validator

    init {
        validator.validate(this)
    }
}
+11
source share
2 answers

In fact, it seems that validation is not responsible for data classes. dataspeaks for itself - it is used to store data.

  • , , @get: , .

  • , , ,

  • , Spring Framework - Bean , , , -:)

0

, , .

-, . . , , , , , .

, , , API . . . .

interface Validatable {

    /**
     * @throws [ValidationErrorException]
     */
    fun validate()
}


class ValidationErrorException(
        val errors: List<ValidationError>
) : Exception() {

    /***
     * Convenience method for getting a data object from the Exception.
     */
    fun toValidationErrors() = ValidationErrors(errors)
}

/**
 * Data object to represent the data of an Exception. Convenient for serialization.
 */
data class ValidationErrors(
        val errors : List<ValidationError>
)

data class ValidationError(
        val path: String,
        val message: String
)

. , javax.validation.Validation:

open class ValidatableJavax : Validatable {

    companion object {
        val validator = Validation.buildDefaultValidatorFactory().validator!!
    }

    override fun validate() {
        val violations = validator.validate(this)
        val errors = violations.map {
            ValidationError(it.propertyPath.toString(), it.message)
        }.toMutableList()
        if (errors.isNotEmpty()) {
            throw ValidationErrorException(errors = errors)
        }
    }
}

, javax- kotlin - :

import javax.validation.constraints.Positive

class MyObject(
        myNumber: BigDecimal
) : ValidatableJavax() {

    @get:Positive(message = "Must be positive")
    val myNumber: BigDecimal = myNumber

}
0

All Articles