Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsIf a Gin PATCH request clears fields it never sent—or your handler cannot distinguish an omitted JSON member from null—the problem is usually not Gin binding. Binding decodes the request; your handler must separately decide which stored fields to leave alone, clear, reject, or replace. Use a request-only patch model that records field presence, then apply each requested change explicitly.
Why does my Gin PATCH request clear fields I didn’t send?
A freshly allocated Go struct starts with zero values. When JSON decoding fills only the members present in a partial request, omitted members remain at those zero values. That is normal decoding behavior; the destructive step is replacing the stored resource—or copying every field from the partial DTO—as though the DTO represented a complete resource.
Gin describes ShouldBindJSON as a shortcut to its JSON binding engine. It decodes into the destination; it does not apply PATCH semantics to your stored model. Gin package documentation
For example, if the stored account has enabled: true and a request contains only {"name":"Ada"}, decoding into a fresh struct leaves its Enabled field false. Replacing the stored account with that struct disables the account, even though the client did not ask for that change.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute#1 Best Overall
What should omission, null, and a value mean?
Decide the contract for each field. A useful state model distinguishes:
- Absent: the JSON object has no member with this key. Usually, leave the stored value unchanged.
- Null: the member is present and its value is JSON
null. The endpoint may clear the value, reject the request, or define another behavior. - Concrete value: the member is present with a value. Validate it, then apply it—including meaningful zero values such as
0,false, or"".
PATCH describes partial modification, but it does not impose one universal meaning for JSON null. The patch document and endpoint contract define the field-level behavior. RFC 5789
Rank #2
Why can’t a pointer or omitempty distinguish missing from null?
A pointer collapses two states
With Go’s legacy encoding/json behavior, unmarshalling JSON null into a pointer sets it to nil. If the key is omitted while decoding into a fresh struct, the pointer also remains nil. A single *T therefore cannot tell those inputs apart. The Go documentation states: “The JSON null value unmarshals into an interface, map, pointer, or slice by setting that Go value to nil.” Go encoding/json documentation
A pointer can still be appropriate when the API only needs to distinguish an absent field from a non-null value, or when null is not accepted and is handled as absent or rejected by the contract. For a scalar, it can also distinguish omission from an explicit zero. It does not alone distinguish omission from null.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Rank #3
omitempty is an output option
omitempty controls whether a field is omitted when marshaling a Go value. It does not record whether a key appeared in an incoming request. Go encoding/json documentation
How should I represent a PATCH field in Go?
Use a request-only DTO rather than binding a partial request directly into the persistent resource. For fields where absent, null, and value have different outcomes, preserve presence explicitly. Three common approaches are:
| Representation | Absent / null / value | Trade-off |
|---|---|---|
| Typed presence wrapper | Can represent all three with a set flag, a null flag, and a value | Clear field-level types; requires wrapper and decoder scaffolding. |
| Custom DTO unmarshalling | Can record which members appeared and decode their values | Keeps the DTO typed; custom decoding code must be maintained and tested. |
map[string]json.RawMessage |
Key lookup detects absence; raw token detects null versus concrete JSON | Flexible, but decoding, type checks, and validation become explicit per key. |
For a wrapper, a typical design has fields such as Set bool, Null bool, and Value T. Its UnmarshalJSON method marks the field as set, checks whether the raw token is null, and otherwise decodes into Value. In Go’s legacy encoding/json, a value type implementing UnmarshalJSON is called for a JSON null token, which makes this pattern possible. Confirm behavior for the actual wrapper shape and decoder in use; the package documentation also describes JSON v2 differences and options. Go Unmarshaler documentation
For example, a field-level application step can express the policy directly:
Best Value
- Used Book in Good Condition
if patch.DisplayName.Set {
if patch.DisplayName.Null {
// Apply the endpoint's documented null behavior: clear or reject.
current.DisplayName = ""
} else {
current.DisplayName = patch.DisplayName.Value
}
}
In a real service, clearing a field may require a nullable storage type rather than assigning an empty string. The important point is that the application code branches on presence and null state instead of inferring intent from a zero value.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.What is the safe order for a Gin PATCH handler?
- Decode the request. Bind into a patch DTO and handle the returned error before touching stored state. Gin distinguishes
Bindmethods, which abort with a 400 response on binding errors, fromShouldBindmethods, which return errors for the handler to process. Gin binding guide - Validate shape and values. Check allowed keys, required combinations, null policy, and field constraints. Do not confuse a decoding failure with a validation failure.
- Load the current resource. Apply the patch to the existing value, not to a zero-valued replacement.
- Apply only present fields. Leave absent values unchanged; handle null and concrete values according to the endpoint contract.
- Persist and respond. Handle persistence errors separately, then return the representation or status required by the API.
Gin’s binding guide notes that JSON-bound fields need JSON tags when their names do not otherwise match. If unknown keys should be rejected, do not assume ordinary ShouldBindJSON does that: Go’s JSON decoder ignores unknown struct keys by default, and strict decoding requires configuring Decoder.DisallowUnknownFields. Check how strict decoding fits the Gin binding version used by the service. Go Decoder documentation
How do I test omitted, null, and zero values?
Test each important field against an existing nonzero stored value. Assert both the HTTP response and the final stored resource.
| Request form | What the test should establish |
|---|---|
| Member omitted | The existing value remains unchanged. |
Member set to null |
The endpoint clears, rejects, or otherwise handles it exactly as documented. |
| Ordinary value | The value is validated and assigned. |
Explicit zero, such as 0 or false |
Zero is applied as an intentional update, not mistaken for omission. |
| Empty string, list, or object | Each empty value has the intended field-specific meaning, distinct from omission where required. |
- Send malformed JSON and check the decode-error response.
- Send invalid field values and check validation behavior.
- If the API rejects unknown keys, send one and verify rejection rather than assuming the binding shortcut is strict.
Which representation should I choose?
Choose based on the endpoint’s semantics and the complexity you are willing to maintain. Typed wrappers make field-level intent and validation easier to read. Custom DTO decoding preserves a typed request shape while recording presence. A raw-message map is useful when keys or patch operations are dynamic, but it places more decoding and validation responsibility in application code.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
For each option, check whether it can represent absent, null, and value distinctly; how it handles nested objects and collections; whether updates avoid altering unrelated state; whether it fits the endpoint’s media type and clients; and how much custom decoding code it adds. Nested objects and collections especially need an explicit contract: replacing a collection, merging it, and clearing it are different operations.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




