feat: support type-level validation for collections via x-not-null extension#1219
Open
YuriiBatkovych wants to merge 2 commits intomainfrom
Open
feat: support type-level validation for collections via x-not-null extension#1219YuriiBatkovych wants to merge 2 commits intomainfrom
YuriiBatkovych wants to merge 2 commits intomainfrom
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem Statement
Currently, the Java/Spring generators primarily apply
@NotNullannotations 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>approvalPolicyIdsThe current
beanValidationCore.mustachedoes not provide a mechanism to inject these annotations into the generic type arguments without manually overriding large portions of thepojo.mustacheorqueryParams.mustachetemplates. 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:
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.
nullable (Item level): In many Java generators, nullable: false is the default assumption. If the generator automatically added
@NotNullto every non-nullable type argument, it would produceList<@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:
Generated Output:
Assuming the parent template is configured to iterate over items, this allows the generation of:
List<@NotNull @Pattern(...) String> customIdsBenefits
Non-Breaking: It uses a vendorExtension, meaning existing users who do not use
x-not-nullwill 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.