Skip to content

Formal Validation with @Validation

Jan Bernitt edited this page May 20, 2026 · 14 revisions

This page is mainly meant as a overview or presentation around the introduction of formal input validation using @Validation as introduced by #23754.

Formal Input Validation

  • context-less (static context)
  • no state
  • no data related validation (just the input itself)
  • no semantic validation

Typical examples

  • property is required, e.g. name
  • number must be be positive, e.g. page
  • text must match a pattern, e.g. a UID
  • set of properties must be defined together, e.g. cc+co => coc

What is @Validation?

@Validation is a declarative Java-API for (a subset of) JSON-schema-validation

🥳 we can extract JSON-schema conform JSON and include it in our OpenAPI documentation to inform clients about expectations that is both human and machine readable

It follows: If input is formally wrong, the caller made an avoidable mistake => BadRequestException

What extend of JSON-schema-validation is supported?

@Validation supports most of the fundamental validations 1:1 as far as they make sense in the context of mapping JSON to Java

The Rules include

  • type (JSON node type)
  • enum (JSON equals from a list of options)
  • string: minLength, maxLength, pattern
  • number: minimum, exclusiveMinimum, maximum, exclusiveMaximum, multipleOf
  • array: minItems, maxItems, uniqueItems
  • object: minProperties, maxProperties, required, dependentRequired

Custom validations can be added using @Validator implementing @Validation.Validator

Where does it apply?

  • In #23754 validation from @Validation is first added to URL request parameter objects
  • Opt-in: by using records that implement UrlParams
  • can easily be extended to request bodies (as validation is JSON based)

But records only to model objects

Why @Validation? (and not bean-validation or alike)

  • uniform validation of URL request parameters and request bodies
  • uniform API: @Validation + @Validator
  • full generic support (e.g. List<@Validation(maxLength=5)String>
  • consistent behaviour as validation and type mapping go hand in hand
  • validation occurs on input (JSON) not Java (which might have lost information or failed to translate masking errors)
  • easy to extend and customize: @Validator + @Validation.Validator + meta-annotations
  • low overhead, fail fast/early
  • allows mixing JSON and Java types
  • full control on this critical feature remains in DHIS2 hands

Meta-Annotations

Clone this wiki locally