Skip to content

feat(v3): express extensions:"x-nullable" as a standard type union#2202

Open
kklem0 wants to merge 1 commit into
swaggo:v2from
sssf-code:feat-v3-nullable-type-union
Open

feat(v3): express extensions:"x-nullable" as a standard type union#2202
kklem0 wants to merge 1 commit into
swaggo:v2from
sssf-code:feat-v3-nullable-type-union

Conversation

@kklem0

@kklem0 kklem0 commented Jul 19, 2026

Copy link
Copy Markdown

Adds a way for annotation-declared nullability to reach the OpenAPI 3.1 output (see umbrella issue).

OpenAPI 3.1 removed the nullable keyword; the standard expression is the type union ["<type>", "null"], and typed-client generators ignore vendor extensions. Previously extensions:"x-nullable" survived only as an x-nullable: true extension, so there was no way to mark a property nullable in the generated 3.1 spec.

With this PR:

PublisherName pgtype.Text `json:"publisher_name" swaggertype:"string" extensions:"x-nullable"`
{"type": ["string", "null"]}

A negated !x-nullable keeps its extension form (non-nullable is already the default). This intentionally changes the extension passthrough behavior for truthy x-nullable; the existing Extensions tag test is updated accordingly, and TestComplementSchemaNullableExtensionV3 covers union conversion, negation, and preservation of other extensions.

Validated on a production codebase: 181 nullable properties now render as standard type unions, matching our swag v1 + swagger2openapi (OpenAPI 3.0 nullable: true) pipeline one-for-one.

OpenAPI 3.1 removed the `nullable` keyword; the standard way to declare
a nullable property is the type union ["<type>", "null"], and typed
client generators ignore vendor extensions. Convert a truthy x-nullable
from the extensions struct tag into the union (and drop the extension)
so nullability from annotations survives into the generated v3.1 spec.
A negated !x-nullable keeps its extension form, since non-nullable is
already the default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.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.

1 participant