Sometimes a type doesn’t have an obvious mapping to JSON.
How would you serialize time.Time
? There are so many possibilities.
Go provides a default JSON mapping for time.Time
. We can implement custom marshaller for user-defined types like structs.
For existing types we can define a new (but compatible) type.
Here’s a custom marshalling and unmarshaling for time.Time
that only serializes year/month/date part:
https://codeeval.dev/gist/686e8b7952bf3a78c3dd27fe2b759f36
Notice that receiver type of UnmashalJSON
is a pointer to the type.
This is necessary for changes to persist outside the function itself.
Consider a struct with both exported and unexported fields:
type MyStruct struct {
uuid string
Name string
}
Imagine you want to Marshal()
this struct into valid JSON for storage in something like etcd.
However, since uuid
in not exported, the json.Marshal()
skips it.
To marshal private fields without making them public we can use a custom marshaller:
https://codeeval.dev/gist/9dc69d886e9faf8db3d8315decb3d075
How does custom marshaling works?
Package JSON defines 2 interfaces: Marshaler
and Unmarshaler
.
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}