Skip to content

Add JsonNullable support to JSON schema generator#6071

Open
jewoodev wants to merge 1 commit into
spring-projects:mainfrom
jewoodev:fix/gh-6046-json-nullable-schema
Open

Add JsonNullable support to JSON schema generator#6071
jewoodev wants to merge 1 commit into
spring-projects:mainfrom
jewoodev:fix/gh-6046-json-nullable-schema

Conversation

@jewoodev
Copy link
Copy Markdown
Contributor

@jewoodev jewoodev commented May 19, 2026

Summary

Adds JsonNullable<T> support to JsonSchemaGenerator, so generated JSON Schemas can model values that may be omitted separately from values explicitly set to null — for both tool inputs and typed schemas.

  • jackson-databind-nullable is an <optional> dependency; JsonNullableSchemaModule registers only when JsonNullable is on the classpath.
  • A single CustomDefinitionProvider unwraps JsonNullable<T> at any position (tool parameters and record/POJO fields) — generating T's schema and adding "null" to the allowed types.
  • Unannotated JsonNullable<T> is treated as not required by default — at both the tool parameter and record/POJO field level — while explicit @ToolParam, @JsonProperty, or @Schema settings still take precedence.

The required default intentionally differs from the generator's PROPERTY_REQUIRED_BY_DEFAULT = true for the unannotated case only — JsonNullable exists precisely so a caller can omit a value, so not-required is the natural fit. Happy to switch to an explicit opt-out if you'd rather keep required-by-default for this wrapper too. The checkstyle suppression is scoped to JsonNullableSchemaModule because the bannedNullabilityImports rule false-positives on the JsonNullable class name.

Testing

Added JUnit coverage in JsonSchemaGeneratorTests for scalar/list/object JsonNullable<T> at top-level parameters and record fields, plus explicit required-policy overrides. ./mvnw package passes locally.

Closes #6046

Recognize org.openapitools.jackson.nullable.JsonNullable<T> when generating
JSON schemas for tool calling and structured output, so the wrapped type T is
exposed and `null` is added to the allowed types.

- Register JsonNullableSchemaModule automatically when JsonNullable is on the
  classpath (jackson-databind-nullable is declared as optional)
- A single CustomDefinitionProvider intercepts JsonNullable<T> at any type
  position, covering top-level parameters as well as record/POJO fields
- Unannotated JsonNullable<T> parameters and fields are treated as
  not-required, while explicit @ToolParam, @JsonProperty, or @Schema settings
  still take precedence

Closes spring-projects#6046

Signed-off-by: jewoodev <jewoos15@naver.com>
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.

Support distinguishing null vs absent fields in MCP tool parameters for partial update operations

1 participant