Comment convertir une Go struct en JSON : du débutant au pro
Travailler avec JSON est le pain quotidien de tout développeur backend Go. Presque chaque jour, vous devez envoyer des données au client, recevoir des requêtes d'une API ou enregistrer des configurations. Et dans 90 % des cas, c'est du JSON. Mais comment transformer correctement votre struct native en JSON lisible ? Cela semble simple, non ? Pourtant, le diable se cache dans les détails : des tags incorrects, des champs vides, des erreurs oubliées — et voilà que votre API ne renvoie pas ce qu'elle devrait.
Dans cet article, nous allons détailler la conversion de Go struct en JSON des bases aux techniques avancées. Vous apprendrez comment fonctionnent les tags, comment masquer les champs vides, comment sérialiser des structures imbriquées et comment éviter les erreurs embarrassantes. C'est parti !
Les bases : le package encoding/json
La bibliothèque standard de Go contient un puissant package encoding/json. Ses principaux outils sont les fonctions json.Marshal (pour transformer une struct en JSON) et json.Unmarshal (pour le processus inverse).
Prenons un exemple de base. Nous avons une structure utilisateur :
package main
import ( "encoding/json" "fmt")
type User struct { Name string Age int Email string}
func main() { user := User{ Name: "Alexei", Age: 30, Email: "alex@example.com", }
jsonData, err := json.Marshal(user) if err != nil { fmt.Println("Erreur :", err) return }
fmt.Println(string(jsonData)) // Sortie : {"Name":"Alexei","Age":30,"Email":"alex@example.com"}}Tout fonctionne, mais il y a un détail : les clés JSON correspondent aux noms des champs de la structure (avec une majuscule). Cela ne respecte pas les standards JSON (on utilise généralement le camelCase ou le snake_case).
Tags JSON : contrôle sur les noms des clés
Pour contrôler l'apparence des champs dans le JSON, on utilise les tags de structure. Ce sont des annotations spéciales écrites après le type du champ entre guillemets inversés.
type User struct { Name string `json:"name"` Age int `json:"age"` Email string `json:"email"`}
// Désormais, la sortie sera :// {"name":"Alexei","age":30,"email":"alex@example.com"}Les tags résolvent plusieurs problèmes à la fois :
- Modification du nom du champ — rendez les clés jolies et lisibles
- Ignorer un champ — avec
json:"-", le champ est totalement exclu du JSON - Gestion des champs vides — l'option
omitemptymasque le champ s'il contient une valeur nulle
Exemple pratique avec omitempty
type User struct { Name string `json:"name"` Age int `json:"age,omitempty"` Email string `json:"email,omitempty"` IsAdmin bool `json:"is_admin,omitempty"`}
func main() { user := User{Name: "Maria"} jsonData, _ := json.Marshal(user) fmt.Println(string(jsonData)) // Sortie : {"name":"Maria"} // Age, Email et IsAdmin sont ignorés car ils sont vides}Notez que omitempty fonctionne pour les valeurs nulles — 0, false, chaîne vide, nil. C'est très pratique pour les API où il n'est pas nécessaire d'inclure des champs superflus.
Structures imbriquées et slices
Dans les projets réels, les données sont rarement plates. Vous avez souvent des objets imbriqués ou des tableaux. Go gère cela parfaitement — le package json traite récursivement tous les champs.
type Address struct { City string `json:"city"` Street string `json:"street"` ZipCode string `json:"zip_code"`}
type Company struct { Name string `json:"name"` Address Address `json:"address"` Tags []string `json:"tags"`}
func main() { company := Company{