1

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?

1 Answer 1

1

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)
}

Go Play Space example

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.