Comment masquer les champs d'une structure en JSON : Go pour débutants et experts

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

La magie du JSON en Go : pourquoi certains champs sont visibles et d'autres non ?

\n

Avez-vous déjà été confronté à une situation où votre structure Go envoie dans la réponse JSON ce que le client n'a pas besoin de voir ? Par exemple, le mot de passe d'un utilisateur, l'ID interne de la base de données ou une clé secrète. Ou, à l'inverse, devez-vous afficher un champ uniquement sous certaines conditions (par exemple, s'il n'est pas vide).

\n

Ce problème est l'un des plus populaires sur Stack Overflow, et pour cause. Travailler avec JSON en Go est un art d'équilibre entre la rigueur des types et la flexibilité de la représentation. Aujourd'hui, nous allons passer en revue toutes les méthodes : du simple tag json:"-" aux solutions personnalisées complexes avec des interfaces. C'est parti !

\n\n

1. La méthode la plus simple : le tag json:"-"

\n

Go permet de contrôler la sérialisation d'une structure via des tags spéciaux. Si vous voulez masquer définitivement un champ du JSON, ajoutez simplement json:"-".

\n
type User struct {\n    Name     string `json:"name"`\n    Password string `json:"-"`\n    Age      int    `json:"age"`\n}\n\nfunc main() {\n    u := User{Name: "Alice", Password: "supersecret", Age: 30}\n    data, _ := json.Marshal(u)\n    fmt.Println(string(data))\n    // Sortie : {"name":"Alice","age":30}\n}
\n

Le champ Password a disparu, comme s'il n'avait jamais existé. Idéal pour les données confidentielles qui ne doivent jamais quitter le serveur.

\n\n

2. Masquage conditionnel : omitempty

\n

Parfois, vous devez masquer un champ uniquement s'il est vide. Pour cela, on utilise l'option omitempty (abréviation de "omit if empty").

\n
type Product struct {\n    Name        string  `json:"name"`\n    Description string  `json:"description,omitempty"`\n    Price       float64 `json:"price,omitempty"`\n}\n\nfunc main() {\n    p1 := Product{Name: "Livre", Price: 500.0}\n    data1, _ := json.Marshal(p1)\n    fmt.Println(string(data1)) // {"name":"Livre","price":500}\n\n    p2 := Product{Name: "Cours"}\n    data2, _ := json.Marshal(p2)\n    fmt.Println(string(data2)) // {"name":"Cours"}\n}
\n

Important : omitempty fonctionne uniquement avec les valeurs "nulles" : "", 0, false, nil (pour les slices, maps, pointeurs).

\n\n

Piège avec les champs numériques

\n

Soyez prudent : si Price est égal à 0, il sera également masqué. Dans certaines logiques métier, cela est inacceptable (un produit gratuit est aussi un prix). Dans ce cas, il est préférable d'utiliser des pointeurs.

\n\n

3. Utilisation de pointeurs (*) et d'interfaces

\n

Les pointeurs sont vos meilleurs amis lorsque vous devez distinguer "valeur non spécifiée" et "valeur égale à zéro".

\n
type UserProfile struct {\n    Name    string  `json:"name"`\n    Age     *int    `json:"age,omitempty"`  // pointeur vers int\n    Bio     *string `json:"bio,omitempty"`\n}\n\nfunc main() {\n    // Âge non spécifié — le champ sera masqué\n    u1 := UserProfile{Name: "Jean"}\n    data1, _ := json.Marshal(u1)\n    fmt.Println(string(data1)) // {"name":"Jean"}\n\n    // Âge = 0 — c'est une valeur significative\n    zero := 0\n    u2 := UserProfile{Name: "Marie", Age: &zero}\n    data2, _ := json.Marshal(u2)\n    fmt.Println(string(data2)) // {"name":"Marie","age":0}\n}
\n

Cette approche est souvent utilisée dans les API REST, où vous devez mettre à jour uniquement les champs transmis (mise à jour partielle, requêtes PATCH).

\n\n

4. Sérialisation personnalisée : l'interface json.Marshaler

\n

Si les tags standards ne suffisent pas, vous pouvez contrôler entièrement le processus. Implémentez l'interface json.Marshaler et écrivez votre propre logique.

\n
type DynamicUser struct {\n    ID        int\n    Name      string\n    ShowEmail bool\n    Email     string\n}\n\nfunc (u DynamicUser) MarshalJSON() ([]byte, error) {\n    // Créer une structure anonyme uniquement pour la sérialisation\n    m := map[string]interface{}{\n        "id":   u.ID,\n        "name": u.Name,\n    }\n    if u.ShowEmail {                

Blogs

Book Recommendations