Introducción al trabajo con JSON en Go
\n\nJSON (JavaScript Object Notation) es uno de los formatos de intercambio de datos más populares en aplicaciones web modernas y microservicios. Gracias a su simplicidad y legibilidad, JSON se ha convertido en el estándar para API REST, archivos de configuración y almacenamiento de datos estructurados.
\n\nEl lenguaje Go (Golang) ofrece soporte integrado y potente para JSON a través del paquete encoding/json. Este paquete permite convertir fácilmente estructuras de Go a JSON (serialización) y viceversa (deserialización o análisis).
En este artículo, analizaremos los fundamentos del trabajo con JSON en Go: desde ejemplos simples hasta el manejo de estructuras anidadas complejas y errores. El material está dirigido a desarrolladores principiantes que ya están familiarizados con los conceptos básicos de la sintaxis de Go.
\n\nSerialización: conversión de estructuras de Go a JSON
\n\nLa serialización (codificación) es el proceso de convertir datos de la representación interna de Go (estructuras, slices, mapas) a una cadena JSON. En Go, se utiliza la función json.Marshal().
Ejemplo básico de serialización
\n\npackage main\n\nimport (\n "encoding/json"\n "fmt"\n)\n\ntype Person struct {\n Name string\n Age int\n City string\n}\n\nfunc main() {\n person := Person{\n Name: "Iván Petrov",\n Age: 30,\n City: "Moscú",\n }\n\n jsonBytes, err := json.Marshal(person)\n if err != nil {\n fmt.Println("Error de serialización:", err)\n return\n }\n\n fmt.Println(string(jsonBytes))\n // Salida: {"Name":"Iván Petrov","Age":30,"City":"Moscú"}\n}\n\nTenga en cuenta: json.Marshal() devuelve un slice de bytes ([]byte), por lo que lo convertimos a cadena con string().
Salida formateada con json.MarshalIndent
\n\nPara depuración o salida legible, use json.MarshalIndent():
jsonBytes, err := json.MarshalIndent(person, "", " ")\nif err != nil {\n fmt.Println("Error:", err)\n return\n}\nfmt.Println(string(jsonBytes))\n// Salida:\n// {\n// "Name": "Iván Petrov",\n// "Age": 30,\n// "City": "Moscú"\n// }\n\nSerialización de slices y mapas
\n\nGo permite serializar no solo estructuras, sino también otros tipos de datos:
\n\n// Slice de estructuras\npeople := []Person{\n {Name: "Ana", Age: 25, City: "SPb"},\n {Name: "Pedro", Age: 35, City: "Kazán"},\n}\njsonBytes, _ := json.Marshal(people)\nfmt.Println(string(jsonBytes))\n// Salida: [{"Name":"Ana","Age":25,"City":"SPb"},{"Name":"Pedro","Age":35,"City":"Kazán"}]\n\n// Mapa\nscores := map[string]int{"Álgebra": 5, "Física": 4, "Informática": 5}\njsonBytes, _ = json.Marshal(scores)\nfmt.Println(string(jsonBytes))\n// Salida: {"Álgebra":5,"Informática":5,"Física":4}\n\nAnálisis JSON: conversión de JSON a estructuras de Go
\n\nEl análisis (deserialización) es el proceso inverso: a partir de una cadena JSON obtenemos una estructura de Go. Para esto se utiliza la función json.Unmarshal().
Análisis en una estructura
\n\npackage main\n\nimport (\n "encoding/json"\n "fmt"\n)\n\ntype Person struct {\n Name string\n Age int\n City string\n}\n\nfunc main() {\n jsonString := `{"Name":"Iván Petrov","Age":30,"City":"Moscú"}`\n\n var person Person\n err := json.Unmarshal([]byte(jsonString), &person)\n if err != nil {\n fmt.Println("Error de análisis:", err)\n return\n }\n\n fmt.Printf("Nombre: %s, Edad: %d, Ciudad: %s\\n", person.Name, person.Age, person.City)\n // Salida: Nombre: Iván Petrov, Edad: 30, Ciudad: Moscú\n}\n\nImportante: pase un puntero a la estructura (&person), de lo contrario Unmarshal no podrá modificar sus campos.
Análisis en map[string]interface{}
\n\nSi la estructura de datos no se conoce de antemano, se puede usar un tipo universal:
\n\njsonString := `{"name":"Ana","