Skip to content

Support three-state optional fields (Optional<T>) for PATCH serialization #1

Description

@OmarAlJarrah

Problem

PATCH and JSON Merge Patch operations need to distinguish three states for each field:

  • absent — omit the field; leave the server value unchanged
  • explicit null — send null; clear the server value
  • present — send a concrete value

Plain nullable types (T?) collapse absent and null into a single representation, so models cannot express partial updates faithfully. The initial serialization layer intentionally ships without a dedicated type for this; consumers must hand-roll converters or fall back to JsonNode.

Proposed direction

Introduce a three-state Optional<T> value type (absent / null / present) with:

  • a System.Text.Json converter, and
  • source-generation support that omits absent members on write.

This is the .NET counterpart to the Tristate<T> container the Java and Python SDKs already provide.

Requirements & considerations

  • Trim-safe and NativeAOT-compatible. The converter and the omit-on-absent behavior must work with source-generated JsonSerializerContexts — no runtime reflection.
  • Omission mechanism. Skipping an absent member cannot be expressed through DefaultIgnoreCondition for a struct; it needs a JsonTypeInfo / ShouldSerialize modifier integrated with the source generator.
  • Additive. This can land after the initial serialization work without changing existing public APIs.
  • Ergonomics. Implicit conversion from T, factory helpers (Optional.Of(value), Optional<T>.Absent), and clean pattern matching.

Out of scope (for now)

  • Full RFC 7386 (JSON Merge Patch) document handling, unless we choose to layer it on top of Optional<T>.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions