ProgrammationDéveloppeur Backend Go

Comment fonctionne la manipulation de JSON (encoding/json) en Go : caractéristiques de la sérialisation, caractéristiques des tags struct, problèmes fréquents lors du marshalling/demarshalling et solutions de contournement ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

En Go, le marshalling JSON est standardisé via le package encoding/json. Seuls les champs exportés (avec une majuscule) des structures peuvent être sérialisés. Pour gérer les noms et le traitement, on utilise des tags struct :

type User struct { ID int `json:"id"` Name string `json:"name,omitempty"` Age int `json:"age,string"` }
  • omitempty exclut le champ si sa valeur est nulle ;
  • string sérialise la valeur comme une chaîne, même si c'est un nombre.

Exemple de sérialisation :

user := User{ID: 1, Name: "Oleg"} b, _ := json.Marshal(user) fmt.Println(string(b)) // {"id":1,"name":"Oleg","age":"0"}

Exemple de parsing JSON

var u User json.Unmarshal([]byte('{"id":2,"name":"Ivan"}'), &u)

Question piège.

Comment les champs non exportés (avec une minuscule) d'une structure sont-ils sérialisés lors du marshalling en JSON ?

Réponse correcte : Ils sont ignorés, seuls les champs exportés (avec une majuscule) participent à la sérialisation. Cela casse souvent l'API de manière surprenante :

type Foo struct { bar int // ne sera pas sérialisé ! }

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet.


Histoire

Le backend fournissait des objets JSON incomplets, car certains champs nécessaires étaient restés non exportés (avec une minuscule). Plusieurs jours ont été nécessaires pour comprendre pourquoi les clients ne voyaient pas ces champs.


Histoire

Dans la réponse de l'API, un champ contenait la construction omitempty, mais parfois une valeur vide arrivait, car la valeur nulle pour un tableau est nil, et non un tableau vide. Les clients recevaient null au lieu d'un tableau vide [] et échouaient lors du parsing.


Histoire

Dans le projet, des champs dynamiques étaient ajoutés aux structures via map[string]interface{}, mais on oubliait de mettre en œuvre un UnmarshalJSON personnalisé, ce qui entraînait la perte de certaines données sans erreur. Les données clients étaient perdues et récupérées manuellement à partir de sauvegardes.