AshOaskit.Schemas.Nullable (AshOasKit v0.2.0)

View Source

Version-aware nullable schema construction for OpenAPI 3.0 and 3.1.

OpenAPI 3.0 and 3.1 represent nullable types differently. This module provides version-dispatched helpers so callers can write make_nullable(schema, version) without branching on the version themselves.

Version Differences

VersionSimple types$ref schemasOther complex schemas
3.0nullable: true added to schemaWrapped in allOf + nullable: true (3.0 ignores siblings of $ref)nullable: true added to schema
3.1type becomes [type, :null] arrayWrapped in oneOf: [%{type: :null}, schema]Wrapped in oneOf: [%{type: :null}, schema]

Which function to use

  • make_nullable/2 — For schemas with a simple :type atom key (e.g., %{type: :string}, %{type: :integer, format: :int32}).

  • make_nullable_oneof/2 — For complex schemas that cannot use the type-array approach: $ref objects, resource identifiers, link objects, or schemas that already contain a :oneOf key.

Relationship to TypeMapper

TypeMapper has its own string-key nullable helpers that operate on "type" string keys for external-facing JSON Schema output. Those are intentionally separate because they handle a different key convention.

Callers

ModuleFunction used
PropertyBuildersmake_nullable/2 (via defdelegate)
RelationshipSchemasmake_nullable/2
ResourceIdentifiermake_nullable_oneof/2
RouteResponsesmake_nullable/2, make_nullable_oneof/2
ResponseLinksmake_nullable_oneof/2
ResponseMetamake_nullable/2

Examples

iex> AshOaskit.Schemas.Nullable.make_nullable(%{type: :string}, "3.0")
%{type: :string, nullable: true}

iex> AshOaskit.Schemas.Nullable.make_nullable(%{type: :string}, "3.1")
%{type: [:string, :null]}

iex> AshOaskit.Schemas.Nullable.make_nullable_oneof(
...>   %{"$ref" => "#/components/schemas/User"},
...>   "3.1"
...> )
%{oneOf: [%{type: :null}, %{"$ref" => "#/components/schemas/User"}]}

Summary

Functions

Makes a schema nullable based on OpenAPI version.

Makes a complex schema nullable using a oneOf wrapper.

Functions

make_nullable(schema, arg2)

@spec make_nullable(map(), String.t()) :: map()

Makes a schema nullable based on OpenAPI version.

For schemas with a simple :type atom key:

  • OpenAPI 3.0: adds nullable: true
  • OpenAPI 3.1: converts type to array [type, :null]

Returns the schema unchanged in 3.1 mode if no :type key is present. Use make_nullable_oneof/2 for complex schemas without a :type key.

Parameters

  • schema - A map with a :type atom key
  • version - OpenAPI version string ("3.0" or "3.1")

Examples

iex> AshOaskit.Schemas.Nullable.make_nullable(%{type: :string}, "3.1")
%{type: [:string, :null]}

iex> AshOaskit.Schemas.Nullable.make_nullable(%{type: :string}, "3.0")
%{type: :string, nullable: true}

iex> AshOaskit.Schemas.Nullable.make_nullable(%{type: :integer, format: :int32}, "3.1")
%{type: [:integer, :null], format: :int32}

iex> AshOaskit.Schemas.Nullable.make_nullable(%{oneOf: [%{type: :string}]}, "3.1")
%{oneOf: [%{type: :string}]}

make_nullable_oneof(schema, arg2)

@spec make_nullable_oneof(map(), String.t()) :: map()

Makes a complex schema nullable using a oneOf wrapper.

For schemas that cannot use the simple type-array approach (e.g., $ref schemas, resource identifiers, link objects):

  • OpenAPI 3.0: adds nullable: true to the schema; $ref schemas are first wrapped in allOf because 3.0 ignores sibling keys next to $ref
  • OpenAPI 3.1: wraps in %{oneOf: [%{type: :null}, schema]}

If the schema already has a :oneOf key, prepends the null type to the existing list instead of double-wrapping.

Parameters

  • schema - Any map representing a JSON Schema
  • version - OpenAPI version string ("3.0" or "3.1")

Examples

iex> AshOaskit.Schemas.Nullable.make_nullable_oneof(%{type: :object, properties: %{}}, "3.0")
%{type: :object, properties: %{}, nullable: true}

iex> AshOaskit.Schemas.Nullable.make_nullable_oneof(
...>   %{"$ref" => "#/components/schemas/User"},
...>   "3.0"
...> )
%{allOf: [%{"$ref" => "#/components/schemas/User"}], nullable: true}

iex> AshOaskit.Schemas.Nullable.make_nullable_oneof(%{type: :object, properties: %{}}, "3.1")
%{oneOf: [%{type: :null}, %{type: :object, properties: %{}}]}

iex> AshOaskit.Schemas.Nullable.make_nullable_oneof(
...>   %{"$ref" => "#/components/schemas/User"},
...>   "3.1"
...> )
%{oneOf: [%{type: :null}, %{"$ref" => "#/components/schemas/User"}]}

iex> AshOaskit.Schemas.Nullable.make_nullable_oneof(
...>   %{oneOf: [%{type: :string}, %{type: :integer}]},
...>   "3.1"
...> )
%{oneOf: [%{type: :null}, %{type: :string}, %{type: :integer}]}