From 4dcce4a070f820c73e5254db0dc76d0a5eb88f47 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 16:23:35 +0000 Subject: [PATCH 1/2] docs: add documentation for nullable types and explicit null overrides - Add nullable to built-in types table - Document the difference between optional and nullable - Explain PATCH request semantics with explicit null values - Provide TypeScript and Java SDK usage examples - Document combining optional and nullable for three-state fields This addresses the need to document explicit null overrides for APIs that need to differentiate between omitted fields, explicit null values, and actual values in PATCH requests. Co-Authored-By: Devin Logan --- fern/products/api-def/ferndef-pages/types.mdx | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/fern/products/api-def/ferndef-pages/types.mdx b/fern/products/api-def/ferndef-pages/types.mdx index c9ef37bcb..99bd97405 100644 --- a/fern/products/api-def/ferndef-pages/types.mdx +++ b/fern/products/api-def/ferndef-pages/types.mdx @@ -22,10 +22,87 @@ Types describe the data model of your API. | `set` | An unordered collection with unique elements, e.g., `set` | | `map` | Key-value mapping, e.g., `map` | | `optional` | Optional value, e.g., `optional` | +| `nullable` | Nullable value that can be explicitly set to `null`, e.g., `nullable` | | `literal` | Literal value, e.g., `literal<"Plants">` | | `file` | File upload type, e.g., [file uploads](/learn/api-definition/fern/endpoints/multipart) | | `unknown` | Represents arbitrary JSON | +### Optional vs Nullable + +Understanding the difference between `optional` and `nullable` is important for properly modeling your API: + +- **`optional`**: The field can be omitted from the request/response entirely. When omitted, the field is not sent over the wire. +- **`nullable`**: The field must be present but can be explicitly set to `null`. This allows you to distinguish between "not specified" and "explicitly cleared". + +```yaml +types: + User: + properties: + name: string + nickname: optional # Can be omitted entirely + bio: nullable # Must be present, but can be null +``` + +This distinction is particularly important for PATCH requests where you need to differentiate between: +1. **Omitting a field** - Don't update this field (keep existing value) +2. **Setting to `null`** - Clear this field (remove the value) +3. **Setting to a value** - Update this field with a new value + +#### Example: PATCH request semantics + +```yaml +types: + UpdateUserRequest: + properties: + nickname: optional # Omit to keep current nickname + bio: nullable # Set to null to clear bio +``` + +**TypeScript SDK usage:** +```typescript +// Don't update nickname, clear bio +await client.users.update({ + bio: null // Explicitly clear the bio field + // nickname is omitted, so it won't be updated +}); + +// Update both fields +await client.users.update({ + nickname: "john_doe", + bio: "Software engineer" +}); +``` + +**Java SDK usage:** +```java +// With collapse-optional-nullable config enabled +UpdateUserRequest.builder() + .nickname(Optional.empty()) // Omit field (don't update) + .bio(OptionalNullable.ofNull()) // Clear field (set to null) + .build(); + +UpdateUserRequest.builder() + .nickname(Optional.of("john_doe")) + .bio(OptionalNullable.of("Software engineer")) + .build(); +``` + +### Combining optional and nullable + +You can combine `optional` and `nullable` to create a field that can be omitted OR explicitly set to null: + +```yaml +types: + User: + properties: + metadata: optional>> +``` + +This creates three possible states: +1. Field omitted entirely +2. Field present with `null` value +3. Field present with actual map data + ## Custom types Creating your own types is easy in Fern! From 9996192b226babcd7bb87f8acea604c1fbf60ebc Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 16:26:25 +0000 Subject: [PATCH 2/2] fix: address vale linting issues - Change heading to sentence-style capitalization - Remove unnecessary adverb 'properly' - Use contraction 'isn't' instead of 'is not' - Add 'HTTP' prefix to PATCH to clarify acronym Co-Authored-By: Devin Logan --- fern/products/api-def/ferndef-pages/types.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fern/products/api-def/ferndef-pages/types.mdx b/fern/products/api-def/ferndef-pages/types.mdx index 99bd97405..fd268fdd6 100644 --- a/fern/products/api-def/ferndef-pages/types.mdx +++ b/fern/products/api-def/ferndef-pages/types.mdx @@ -27,11 +27,11 @@ Types describe the data model of your API. | `file` | File upload type, e.g., [file uploads](/learn/api-definition/fern/endpoints/multipart) | | `unknown` | Represents arbitrary JSON | -### Optional vs Nullable +### Optional vs nullable -Understanding the difference between `optional` and `nullable` is important for properly modeling your API: +Understanding the difference between `optional` and `nullable` is important for modeling your API: -- **`optional`**: The field can be omitted from the request/response entirely. When omitted, the field is not sent over the wire. +- **`optional`**: The field can be omitted from the request/response entirely. When omitted, the field isn't sent over the wire. - **`nullable`**: The field must be present but can be explicitly set to `null`. This allows you to distinguish between "not specified" and "explicitly cleared". ```yaml @@ -43,12 +43,12 @@ types: bio: nullable # Must be present, but can be null ``` -This distinction is particularly important for PATCH requests where you need to differentiate between: +This distinction is particularly important for HTTP PATCH requests where you need to differentiate between: 1. **Omitting a field** - Don't update this field (keep existing value) 2. **Setting to `null`** - Clear this field (remove the value) 3. **Setting to a value** - Update this field with a new value -#### Example: PATCH request semantics +#### Example: HTTP PATCH request semantics ```yaml types: