Lets say I have two struct that are related like this:
type SecretUser struct {
UserInfo `json:"userInfo"`
Password string `json:"password"`
}
type UserInfo struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Email string `json:"email"`
}
And I receive a JSON in this form:
{
"firstName": "nice",
"lastName":"guy",
"email":"[email protected]",
"password":"abc123"
}
I want to unmarshall this JSON into a SecretUser. Is there a better way than doing it like this?
func (u *User) UnmarshalJSON(data []byte) error {
var objmap map[string]*json.RawMessage
var password string
var err error
err = json.Unmarshal(data, &objmap)
if err != nil {
return err
}
if err := json.Unmarshal(data, &u.UserInfo); err != nil {
return err
}
err = json.Unmarshal(*objmap["password"], &password)
if err != nil {
return err
}
u.Password = password
return nil
}
Basically, I partially unmarshall the JSON into a UserInfo struct and then read it again to extract the password. I don't want to create another struct for just unmarshalling this JSON cleanly or use an external library (unless it's part of the standard). Is there a more clean/efficient way of doing this, without reading the JSON twice or setting every field manually from a map?
CodePudding user response:
Simply include the UserData into the SecretUser struct and do not specify a json tag for it.
type UserInfo struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Email string `json:"email"`
}
type SecretUser struct {
UserInfo
Password string `json:"password"`
}
func main() {
data := []byte(`{"firstName": "nice","lastName":"guy","email":"[email protected]","password":"abc123"}`)
var u SecretUser
json.Unmarshal(data, &u)
fmt.Println(u)
}