web-dev-qa-db-fra.com

Comment ignorer les champs JSON lors du marshaling et non du dé-marshalling

Supposons que j'ai un champ de mot de passe dans une structure utilisateur.

type User struct{
   UserName string `json:"username"`
   Password string `json:"-"`
}

Mes clients enregistrent leurs utilisateurs en affichant ensemble leur nom d'utilisateur et leur mot de passe. Donc, si je décode JSON en struct ci-dessus, il ignore le mot de passe. C'est attendu. Mais je me suis demandé s'il y avait un moyen d'ignorer les champs lors du seul marshaling. J'ai vérifié la page de documentation officielle, mais je n'ai rien trouvé.

https://golang.org/pkg/encoding/json/

Je peux ajouter un champ supplémentaire dans la structure, mais je dois d'abord savoir s'il est possible de le faire avec la bibliothèque JSON.

11
RockOnGom

Une approche courante consiste à utiliser un type ou une variable temporaire, avec la même structure, mais différentes balises json ou même une structure différente:

type User struct {
    UserName string `json:"username"`
    Password string `json:"password"`
}

func (usr User) MarshalJSON() ([]byte, error) {
    var tmp struct {
        UserName string `json:"username"`
    }
    tmp.UserName = usr.UserName
    return json.Marshal(&tmp)
}
12
Kaveh Shahbazian

Comme pour toutes les exigences de marshaling/démarshaling personnalisées dans Go, votre meilleur pari est de chercher à implémenter json.Marshaler/json.Unmarshaler interface sur un type personnalisé.

Dans ce cas, vous pouvez le faire pour le champ de mot de passe:

// Use an explicit password type.
type password string

type User struct{
    UserName string   `json:"username"`
    Password password `json:"password"`
}

// Marshaler ignores the field value completely.
func (password) MarshalJSON() ([]byte, error) {
    return []byte(`""`), nil
}

Notez qu'en ne mettant pas en œuvre json.Unmarshaler, type password conserve le comportement par défaut de son type sous-jacent (string), ce qui permet de désarchiver la structure avec la valeur Password.

Exemple de travail: https://play.golang.org/p/HZQoCKm0vN

8
abhink

Je préfère la composition typographique. Par exemple:

type User struct {
    UserName string `json:"username"`
}

type UserWithPassword struct {
    *User
    Password string `json:"password"`
}

utilisez UserWithPassword lors de la réception de données (par exemple, création/modification d'un utilisateur) et User lors de leur renvoi (authentification).

3
makeroo