Skip to content

feat: support type-level validation for collections via x-not-null extension#1219

Open
YuriiBatkovych wants to merge 2 commits intomainfrom
feat/enable-custom-not-null-validation
Open

feat: support type-level validation for collections via x-not-null extension#1219
YuriiBatkovych wants to merge 2 commits intomainfrom
feat/enable-custom-not-null-validation

Conversation

@YuriiBatkovych
Copy link
Collaborator

@YuriiBatkovych YuriiBatkovych commented Mar 3, 2026

Problem Statement

Currently, the Java/Spring generators primarily apply @NotNull annotations to the container itself (the List or Set) rather than the elements inside the container.

We would like to validate the contents of a collection using "Type Use" annotations, for example:
java.util.List<@NotNull @Pattern(...) String> approvalPolicyIds

The current beanValidationCore.mustache does not provide a mechanism to inject these annotations into the generic type arguments without manually overriding large portions of the pojo.mustache or queryParams.mustache templates. This makes it difficult to enforce non-null constraints on individual items within an array.

Why required and nullable are insufficient

In the OpenAPI specification, the required and nullable keywords have specific behaviors that do not map 1:1 to Java Type Argument validation:

  1. required (Parent level): When an array is marked as required in a schema, it means the List itself must be present in the JSON. It does not dictate whether the elements inside that list can be null.

  2. nullable (Item level): In many Java generators, nullable: false is the default assumption. If the generator automatically added @NotNull to every non-nullable type argument, it would produce List<@NotNull String> for every single array in the project. This would be a massive breaking change and often causes compilation errors with older Java versions or specific serialization frameworks.

Proposed Solution

I am proposing the addition of a new vendor extension, x-not-null, within the beanValidationCore.mustache template.

By adding this check to the core validation partial, users can explicitly trigger a @jakarta.validation.constraints.NotNull annotation at the element level by defining it in their OpenAPI specification.

Changes in beanValidationCore.mustache:

Handlebars
{{#vendorExtensions.x-not-null}}@jakarta.validation.constraints.NotNull {{/vendorExtensions.x-not-null}}

Usage Example

With this change, a user can define their schema as follows to achieve type-level validation:

customIds:
  type: array
  items:
    type: string
    x-not-null: true
    pattern: "^[0-9a-fA-F]{32}$"

Generated Output:
Assuming the parent template is configured to iterate over items, this allows the generation of:
List<@NotNull @Pattern(...) String> customIds

Benefits

  • Non-Breaking: It uses a vendorExtension, meaning existing users who do not use x-not-null will see zero change in their generated code.

  • Precision: Allows developers to distinguish between a "Required List" and "Required items within a List."

  • Standardization: Follows the existing pattern of using vendor extensions to fill gaps in the standard OpenAPI-to-Java mapping.

@YuriiBatkovych YuriiBatkovych requested a review from jjjasper March 3, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant