We break down why
json.Unmarshal checks only the format and basic types, but not the meaning of the data, and how to build the discipline of
decode → normalize → validate. We’ll talk about required fields and
zero values, when it makes sense to use pointers (for example,
*
int), how to write
Validate() with early returns or via
errors.Join, how to diagnose broken JSON using
errors.As and
*json.SyntaxError, and why
omitempty does not make a field “optional”.