1

I'm trying to validate RequestBody using my custom annotations.

With configuration below my validation works:

data class PlayerRegistration(
    @field: Email
    val email: String,
    @field: Pattern(regexp = NICK_REGEX)
    @field: Size(min = 5, max = 15)
    val nick: String,
    @field: Pattern(regexp = PASSWORD_REGEX)
    @field: Size(min = 8, max = 20)
    val password: String,
    val birthDate: LocalDate
)

But when I try to sum up annotations like this:

data class PlayerRegistration(
    @field: Email
    val email: String,
    @field: ValidNick
    val nick: String,
    @field: ValidPassword
    val password: String,
    val birthDate: LocalDate
)

@Pattern(regexp = NICK_REGEX)
@Size(min = 5, max = 15)
@Target(AnnotationTarget.FIELD)
private annotation class ValidNick

@Pattern(regexp = EMAIL_REGEX)
@Size(min = 8, max = 20)
@Target(AnnotationTarget.FIELD)
private annotation class ValidPassword

It doesn't work. What am I doing wrong?

  • Is this related to the fact that you cannot inherit annotations in Kotlin: https://stackoverflow.com/q/51608924/1515052 – Simulant Apr 16 '19 at 16:18

1 Answers1

1

In short: your approach creates annotations that have annotations - two levels of nesting. It's not a mechanism to group annotations.

Try to think like an annotation processor. In the first code snippet, the processor sees a field nick and thinks "OK, I know how to apply Pattern and Size to a field".

In the second code snippet, for the field nick it sees ValidNick and thinks "I don't know this type of annotation, and I don't know how to treat it as a field constraint". The processor would have to know that it has to go to this annotation's annotations, and that's - I believe - is not supported out of the box.

If I were you, I wouldn't push towards such code structure. IMO it decreases the readability because in order to know nick's constraints, you have to go to some other part of the code. In theory it would be reusable, but the question is: how many reuses you would have?

If you really want to achieve something similar, instead of annotations, I'd give delegated properties a try. They let you intercept the setter, and keep such interception logic as a reusable class

PiotrK
  • 1,502
  • 1
  • 15
  • 33