When unmarshalling a value from JSON text, the json
package does not require that all fields to be present in JSON, nor that all JSON fields have a matching Go field.
So you don't have anything special to do, just unmarshal what you have to a Go value what you want or may want.
One thing to note is that if a field is missing in the JSON text, the json
package will not change the corresponding Go field, so if you start with a "fresh", zero value, the field will be left with the zero value of its type.
Most of the time this is enough to detect the presence or absence of a field (in JSON), for example if in the Go struct you have a SortBy
field of type string
, if this is missing in JSON, it will remain the empty string
: ""
.
If the zero value is something useful and valid, then you may turn to use pointers. For example if in your application the empty string
would be a valid SortBy
value, you may declare this field to be a pointer: *string
. And in this case if it's missing in the JSON text, it will remain nil
, the zero value for any pointer type.
See this example:
type Data struct {
I int
S string
P *string
}
func main() {
var d Data
var err error
d, err = Data{}, nil
err = json.Unmarshal([]byte(`{"I":1, "S":"sv", "P":"pv"}`), &d)
fmt.Printf("%#v %v
", d, err)
d, err = Data{}, nil
err = json.Unmarshal([]byte(`{"I":1}`), &d)
fmt.Printf("%#v %v
", d, err)
d, err = Data{}, nil
err = json.Unmarshal([]byte(`{"S":"abc"}`), &d)
fmt.Printf("%#v %v
", d, err)
}
Output (try it on the Go Playground):
main.Data{I:1, S:"sv", P:(*string)(0x1050a150)} <nil>
main.Data{I:1, S:"", P:(*string)(nil)} <nil>
main.Data{I:0, S:"abc", P:(*string)(nil)} <nil>