Json Struct Tags
Fast recall
Quick revision
Core answer
json:"name" controls the JSON key, json:"name,omitempty" skips zero values, json:"-" excludes entirely. They map Go field names to wire-format keys.Whether you understand Json Struct Tags beyond memorized syntax.
Giving a definition without explaining a practical trade-off.
Connect the concept to a small production example and state its complexity or failure mode.
Interview-ready guide
Interview answer
The tag is the mapping:
type User struct {
Name string `json:"name"` // the JSON key is "name"
Email string `json:"email"`
Age int `json:"age,omitempty"` // skip when 0
Password string `json:"-"` // NEVER serialized
notes string // unexported — also never
}
// Marshal(User{Name:"Al", Email:"a@x"}):
// {"name":"Al","email":"a@x"} — Age skipped (0), Password excluded, notes invisible — verifiedThe three controls the tag gives:
- 1The key name:
json:"custom_name"— the Go field and the JSON key can differ freely - 2omitempty: skip when the value is the type's zero (0, "", nil, false, empty slice/map)
- 3The dash:
json:"-"— never marshal, never unmarshal (the security boundary for Password, internal state)
The tag format is strict: the space-separated convention is json:"key,option1,option2". A malformed tag silently falls back to default behavior (no error — the encoding/json package ignores what it can't parse).
The API-design use: tags ARE the wire contract. Your Go struct defines the domain; the tags define what the API looks like — and they're right there in the type declaration, greppable, diff-able, and compile-checked (unlike a separate serializer config).
Json Struct Tags
Direct Answer
Backtick annotations on struct fields: json:"name" controls the JSON key, json:"name,omitempty" skips zero values, json:"-" excludes entirely. They map Go field names to wire-format keys.
Deep Dive & Architecture
The tag parsing, mechanically: encoding/json reads the tag via reflect.StructTag.Lookup("json") — the reflect package exposes the backtick-annotated string; the json package splits it on commas (key first, then options). A tag that fails its grammar (json:"name") — missing the closing quote — is silently skipped, not errored: the field uses the default (Go field name). No compile-time validation exists — a typo in a tag is a runtime-visible surprise.
The omitempty zero-value trap, with the fix: a struct where Age int json:"age,omitempty" — a legitimate age of 0 disappears from the JSON. The consumer can't distinguish 'no age' from 'age zero.' The fixes: (1) *int — nil is omitted, a pointer to 0 is included; (2) a custom MarshalJSON that checks semantic emptiness; (3) drop omitempty for fields where zero is data. The pointer is the idiom for API types where this distinction matters (counts, scores, coordinates).
The unmarshal side's tag subtlety: on decode, tags match the same way — but the case-insensitive fallback means {"Name"} fills a field tagged json:"name" (the exact match is tried first; case-insensitive is the fallback for compatibility). DisallowUnknownFields (the Decoder method) turns the default 'silently drop unknown keys' into an error — the strictness flag for contract-enforcing APIs.
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- When would you use Json Struct Tags in a real project?
- How would you compare Json Struct Tags with an alternative?
- What is a common mistake when using Json Struct Tags?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.