|
223 | 223 | { key: "description", header: "Description" },
|
224 | 224 | ]}
|
225 | 225 | />
|
| 226 | + |
| 227 | +## Nullable and optional field handling |
| 228 | + |
| 229 | +```yml |
| 230 | +go: |
| 231 | + nullableOptionalWrapper: true |
| 232 | +``` |
| 233 | + |
| 234 | +<Table |
| 235 | + data={[ |
| 236 | + { |
| 237 | + name: "nullableOptionalWrapper", |
| 238 | + required: "false", |
| 239 | + default: "newSDK", |
| 240 | + description: |
| 241 | + "When enabled, fields that are both optional and nullable in the source schema are generated using a wrapper type with explicit presence semantics: `optionalnullable.OptionalNullable[T]`. Defaults to `true` for new Go SDKs and `false` for existing SDKs to avoid breaking changes.", |
| 242 | + }, |
| 243 | + ]} |
| 244 | + columns={[ |
| 245 | + { key: "name", header: "Name" }, |
| 246 | + { key: "required", header: "Required" }, |
| 247 | + { key: "default", header: "Default Value" }, |
| 248 | + { key: "description", header: "Description" }, |
| 249 | + ]} |
| 250 | +/> |
| 251 | + |
| 252 | +### When it applies |
| 253 | + |
| 254 | +The wrapper is generated only for fields that are: |
| 255 | + |
| 256 | +- Optional (the property is not listed in the parent schema's `required` array) |
| 257 | +- Nullable (the property `type` includes `"null"` in OpenAPI 3.1) |
| 258 | + |
| 259 | +For example, the following JSON Schema (OpenAPI 3.1) defines an optional, nullable `nickname`: |
| 260 | + |
| 261 | +```yaml |
| 262 | +type: object |
| 263 | +required: |
| 264 | + - id |
| 265 | +properties: |
| 266 | + id: |
| 267 | + type: string |
| 268 | + nickname: |
| 269 | + type: |
| 270 | + - string |
| 271 | + - "null" |
| 272 | +``` |
| 273 | + |
| 274 | +### Generated code |
| 275 | + |
| 276 | +With `nullableOptionalWrapper: true`, the corresponding Go model uses a wrapper type: |
| 277 | + |
| 278 | +```go |
| 279 | +type Pet struct { |
| 280 | + ID string `json:"id"` |
| 281 | + Nickname optionalnullable.OptionalNullable[string] `json:"nickname,omitempty"` |
| 282 | +} |
| 283 | +``` |
| 284 | + |
| 285 | +Without the wrapper (when disabled for existing SDKs), the same field may be generated as a pointer type. |
| 286 | + |
| 287 | +### Using the wrapper |
| 288 | + |
| 289 | +Set values using helper constructors on `OptionalNullable` and retrieve values via `Get()`, which returns `(*T, bool)` — `ok` indicates presence, and a `nil` pointer indicates an explicit null value: |
| 290 | + |
| 291 | +```go |
| 292 | +// Set a present, non-null value |
| 293 | +pet := shared.Pet{} |
| 294 | +nickname := "Finn" |
| 295 | +pet.Nickname = optionalnullable.From(&nickname) |
| 296 | + |
| 297 | +// Read a value |
| 298 | +if val, ok := pet.Nickname.Get(); ok { |
| 299 | + if val == nil { |
| 300 | + fmt.Println("nickname is explicitly null") |
| 301 | + } else { |
| 302 | + fmt.Println("nickname:", *val) |
| 303 | + } |
| 304 | +} else { |
| 305 | + fmt.Println("nickname not set") |
| 306 | +} |
| 307 | +``` |
| 308 | + |
| 309 | +Enabling this flag changes the generated field type and how values are set and read. This is a breaking change for existing SDKs and requires migrating code that accessed those fields directly or through pointer checks to use `optionalnullable.From(...)` and `.Get()`. |
0 commit comments