Pragmatic.Patch
Source-generated PATCH DTOs with tri-state semantics for HTTP PATCH.
The Problem
Section titled “The Problem”A nullable property can’t express the three states a PATCH request needs:
| State | Meaning | JSON |
|---|---|---|
| Field not sent | Don’t touch it | key absent |
| Field explicitly null | Clear it | "name": null |
| Field has a value | Update it | "name": "Alice" |
A string? collapses “not sent” and “set to null” into the same null. So hand-rolled PATCH endpoints
either overwrite unmentioned fields with null (data loss), skip nulls (can’t clear a field), or demand
the full object (defeating PATCH).
// Without Pragmatic.Patch: ambiguouspublic class UpdateGuestRequest{ public string? FirstName { get; set; } // null = "clear it" or "don't touch"?}The Solution
Section titled “The Solution”Optional<T> (a readonly struct with explicit tri-state) plus source-generated patch types. The
generator emits the apply logic that updates only the properties that were actually sent, and tracks
ModifiedProperties for change-aware validation/persistence.
[Patch<Guest>]public partial class PatchGuestRequest{ public Optional<string> FirstName { get; init; } public Optional<string?> Phone { get; init; } // can be sent-as-null to clear}
// Only sent fields are applied; "not sent" is left untouchedpatch.ApplyTo(guest);Installation
Section titled “Installation”dotnet add package Pragmatic.Patchdotnet add package Pragmatic.SourceGenerator # generates the patch typesStatus
Section titled “Status”Optional<T>, [Patch<T>] generation, JSON deserialization, and ModifiedProperties tracking are
functional within the 0.8 preview. See the roadmap.
| Concepts | Tri-state, Optional<T>, generated apply logic, change tracking |
| Getting Started | Your first patch DTO and ApplyTo |
| Tri-State Semantics | not-sent vs null vs value, JSON mapping, edge cases |
| Common Mistakes | The most frequent patch pitfalls |
| Troubleshooting | Problem/solution guide with diagnostics |
Requirements
Section titled “Requirements”- .NET 10.0+
Pragmatic.SourceGeneratoranalyzer
License
Section titled “License”Part of the Pragmatic.Design ecosystem — see Licensing. Pragmatic.Patch is MIT-licensed.