Procesamiento de JSON en Go (Golang): desde lo básico hasta técnicas avanzadas
Go (Golang) ofrece un conjunto de herramientas potente e intuitivo para trabajar con JSON. La biblioteca estándar encoding/json cubre el 95% de las tareas, y para proyectos de alta carga existen alternativas más eficientes. En este artículo, analizaremos todos los aspectos del procesamiento de JSON en Go: desde la serialización básica hasta analizadores personalizados y optimización.
1. Conceptos básicos: la biblioteca estándar encoding/json
En Go, JSON se procesa a través del paquete encoding/json. Las operaciones principales son el marshal (serialización a JSON) y el unmarshal (deserialización desde JSON).
1.1. Marshal (struct → JSON)
Para convertir una estructura de Go a JSON se utiliza la función 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 - omitir si está vacío}
func main() { user := User{ Name: "Iván Petrov", Age: 30, Email: "ivan@example.com", }
jsonData, err := json.Marshal(user) if err != nil { log.Fatal(err) }
fmt.Println(string(jsonData)) // {"name":"Iván Petrov","age":30,"email":"ivan@example.com"}}Importante: Los campos de la estructura deben ser exportables (con mayúscula inicial). Las etiquetas json:"fieldname" controlan el nombre de los campos en JSON.
1.2. Unmarshal (JSON → struct)
Para la conversión inversa se utiliza json.Unmarshal():
func main() { jsonString := `{"name":"Ana","age":25,"email":"anna@mail.com"}` var user User err := json.Unmarshal([]byte(jsonString), &user) if err != nil { log.Fatal(err) }
fmt.Printf("Nombre: %s, Edad: %d", user.Name, user.Age) // Nombre: Ana, Edad: 25}2. Trabajo con estructuras anidadas y arreglos
JSON a menudo contiene objetos y arreglos anidados. En Go, esto se representa con estructuras anidadas y 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":"María","age":32,"email":"maria@tech.com"} ], "address": { "city": "Moscú", "street": "Tverskaya, 10", "zip_code": "101000" } }`
var company Company json.Unmarshal([]byte(companyJSON), &company) fmt.Printf("Empresa: %s, Ciudad: %s, Empleados: %d", company.Name, company.Address.City, len(company.Employees))}3. Técnicas avanzadas
3.1. Serialización personalizada (interfaces Marshaler/Unmarshaler)
A veces es necesario controlar cómo se convierte un tipo a JSON. Para ello, se implementan las interfaces json.Marshaler y 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 También en la biblioteca
Disruptor Java: guía completa con ejemplos prácticos
Métricas de Prometheus en TypeScript: guía completa de client.js
Polars para Rust: guía completa con ejemplos prácticos
Procesamiento de imágenes en Node.js: bibliotecas Sharp, Jimp y gm