Traitement JSON en Go (Golang) : des bases aux techniques avancées
Go (Golang) propose un ensemble d'outils puissants et intuitifs pour travailler avec JSON. La bibliothèque standard encoding/json couvre 95% des tâches, et pour les projets à forte charge, il existe des alternatives plus performantes. Dans cet article, nous aborderons tous les aspects du traitement JSON en Go : de la sérialisation de base aux analyseurs personnalisés et à l'optimisation.
1. Bases : la bibliothèque standard encoding/json
En Go, JSON est traité via le package encoding/json. Les opérations principales sont le marshalling (sérialisation en JSON) et l'unmarshalling (désérialisation depuis JSON).
1.1. Marshalling (struct → JSON)
Pour convertir une structure Go en JSON, on utilise la fonction json.Marshal() :
package main
import ( "encoding/json" "fmt" "log")
type User struct { Name string `json:"name"` Age int `json:"age"` Email string `json:"email,omitempty"` // omitempty - ignorer si vide}
func main() { user := User{ Name: "Ivan Petrov", Age: 30, Email: "ivan@example.com", }
jsonData, err := json.Marshal(user) if err != nil { log.Fatal(err) }
fmt.Println(string(jsonData)) // {"name":"Ivan Petrov","age":30,"email":"ivan@example.com"}}Important : Les champs de la structure doivent être exportables (commencer par une majuscule). Les tags json:"fieldname" contrôlent le nommage des champs en JSON.
1.2. Unmarshalling (JSON → struct)
Pour la conversion inverse, on utilise json.Unmarshal() :
func main() { jsonString := `{"name":"Anna","age":25,"email":"anna@mail.com"}` var user User err := json.Unmarshal([]byte(jsonString), &user) if err != nil { log.Fatal(err) }
fmt.Printf("Nom : %s, Âge : %d", user.Name, user.Age) // Nom : Anna, Âge : 25}2. Travail avec les structures imbriquées et les tableaux
JSON contient souvent des objets imbriqués et des tableaux. En Go, cela se traduit par des structures imbriquées et des slices :
type Address struct { City string `json:"city"` Street string `json:"street"` ZipCode string `json:"zip_code"`}
type Company struct { Name string `json:"name"` Employees []User `json:"employees"` Address Address `json:"address"`}
func main() { companyJSON := `{ "name": "TechCorp", "employees": [ {"name":"Oleg","age":28,"email":"oleg@tech.com"}, {"name":"Maria","age":32,"email":"maria@tech.com"} ], "address": { "city": "Moscou", "street": "Tverskaya, 10", "zip_code": "101000" } }`
var company Company json.Unmarshal([]byte(companyJSON), &company) fmt.Printf("Entreprise : %s, Ville : %s, Employés : %d", company.Name, company.Address.City, len(company.Employees))}3. Techniques avancées
3.1. Sérialisation personnalisée (interfaces Marshaler/Unmarshaler)
Parfois, il est nécessaire de contrôler comment un type est converti en JSON. Pour cela, on implémente les interfaces json.Marshaler et json.Unmarshaler :
type CustomTime struct { time.Time}
const layout = "2006-01-02T15:04:05Z"
func (ct CustomTime) MarshalJSON() ([]byte, error) { return json.Marshal(ct.Format(layout))}
func (ct *CustomTime) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } t, err := time.Parse(layout, s) if err != nil { return err } ct.Time = t return nil}
type Event struct { Title string `json:"title"` Date CustomTime `js Aussi dans la bibliothèque
Parsing HTML en Java : meilleures bibliothèques et exemples de code