Skip to content

Commit 6ee5b81

Browse files
committed
Sync open source content 🐝 (from fe36b8af1344ac7d01a26db0777fadf8355518f1)
1 parent 8352d2a commit 6ee5b81

File tree

1 file changed

+86
-1
lines changed

1 file changed

+86
-1
lines changed

openapi/schemas/null.mdx

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Null in OpenAPI best practices
3-
description: Describing null values in OpenAPI schemas in OpenAPI 3.0.X and 3.1.X.
3+
description: Describing null values in OpenAPI schemas in OpenAPI 3.0.X and 3.1.X, including guidance on combining optional and nullable fields.
44
---
55

66
# null in OpenAPI
@@ -69,3 +69,88 @@ schema:
6969
- type: 'null'
7070
- type: string
7171
```
72+
73+
## Optional vs. nullable vs. optional + nullable
74+
75+
In OpenAPI, **optional** and **nullable** are two separate concepts that are often confused:
76+
77+
- **Optional** means a property can be omitted from the request or response body entirely. A property is optional when it is _not_ listed in the `required` array of its parent object.
78+
- **Nullable** means a property can be explicitly set to `null`.
79+
80+
When a field is only **optional** (not required, not nullable), the API expects either a valid value or for the field to be omitted:
81+
82+
```yaml
83+
# An optional string field (can be "hello" or omitted entirely)
84+
schema:
85+
type: object
86+
properties:
87+
nickname:
88+
type: string
89+
```
90+
91+
When a field is only **nullable** (required, but nullable), the API expects the field to always be present, but it can be set to `null`:
92+
93+
```yaml
94+
# A required but nullable string field (can be "hello" or null, but must be present)
95+
# OpenAPI 3.0.X
96+
schema:
97+
type: object
98+
properties:
99+
nickname:
100+
type: string
101+
nullable: true
102+
required:
103+
- nickname
104+
105+
# OpenAPI v3.1
106+
schema:
107+
type: object
108+
properties:
109+
nickname:
110+
type: ['null', 'string']
111+
required:
112+
- nickname
113+
```
114+
115+
### When a field is both optional and nullable
116+
117+
Marking a field as both optional _and_ nullable introduces three distinct states:
118+
119+
| State | JSON representation | Meaning |
120+
| --- | --- | --- |
121+
| **Value present** | `{ "nickname": "hello" }` | The field is set to a value |
122+
| **Explicitly null** | `{ "nickname": null }` | The field is present but intentionally null |
123+
| **Omitted** | `{ }` | The field is not included at all |
124+
125+
```yaml
126+
# An optional AND nullable field — three possible states
127+
# OpenAPI 3.0.X
128+
schema:
129+
type: object
130+
properties:
131+
nickname:
132+
type: string
133+
nullable: true
134+
135+
# OpenAPI v3.1
136+
schema:
137+
type: object
138+
properties:
139+
nickname:
140+
type: ['null', 'string']
141+
```
142+
143+
This is valid OpenAPI, but it adds real complexity for API consumers. SDK generators need to use special wrapper types to let users express all three states, since a simple pointer or `Optional` type can only distinguish between two states (set vs. unset).
144+
145+
### When to use optional + nullable
146+
147+
Only mark a field as both optional and nullable when the API genuinely treats `null` and omitted differently. Common examples include:
148+
149+
- **PATCH endpoints** where omitting a field means "don't change this value" and sending `null` means "clear this value"
150+
- **Sparse update APIs** that distinguish between "no update" and "reset to default"
151+
152+
### When to remove nullable from optional fields
153+
154+
If the API treats `null` and omitted the same way, remove the `nullable` modifier and keep the field as just optional. Combining optional and nullable when they have the same effect is a common specification mistake that makes generated SDKs harder to use without any benefit.
155+
156+
As a rule of thumb: if you can't describe a scenario where sending `{ "field": null }` and `{ }` should produce different outcomes, the field should be optional but **not** nullable.

0 commit comments

Comments
 (0)