Introdução ao trabalho com JSON em Go
\n\nJSON (JavaScript Object Notation) é um dos formatos de troca de dados mais populares em aplicações web modernas e microsserviços. Graças à sua simplicidade e legibilidade, o JSON se tornou padrão para APIs REST, arquivos de configuração e armazenamento de dados estruturados.
\n\nA linguagem Go (Golang) oferece suporte nativo poderoso para JSON através do pacote encoding/json. Este pacote permite converter facilmente estruturas Go para JSON (serialização) e vice-versa (desserialização ou parsing).
Neste artigo, abordaremos os fundamentos do trabalho com JSON em Go: desde exemplos simples até o tratamento de estruturas aninhadas complexas e erros. O material é voltado para desenvolvedores iniciantes que já conhecem os conceitos básicos da sintaxe do Go.
\n\nSerialização: convertendo estruturas Go para JSON
\n\nSerialização (codificação) é o processo de converter dados da representação interna do Go (structs, slices, maps) em uma string JSON. Em Go, utiliza-se a função json.Marshal().
Exemplo básico de serialização
\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: "João Silva",\n Age: 30,\n City: "São Paulo",\n }\n\n jsonBytes, err := json.Marshal(person)\n if err != nil {\n fmt.Println("Erro de serialização:", err)\n return\n }\n\n fmt.Println(string(jsonBytes))\n // Saída: {"Name":"João Silva","Age":30,"City":"São Paulo"}\n}\n\nObserve: json.Marshal() retorna um slice de bytes ([]byte), por isso o convertemos para string usando string().
Saída formatada com json.MarshalIndent
\n\nPara depuração ou exibição legível, use json.MarshalIndent():
jsonBytes, err := json.MarshalIndent(person, "", " ")\nif err != nil {\n fmt.Println("Erro:", err)\n return\n}\nfmt.Println(string(jsonBytes))\n// Saída:\n// {\n// "Name": "João Silva",\n// "Age": 30,\n// "City": "São Paulo"\n// }\n\nSerialização de slices e maps
\n\nGo permite serializar não apenas structs, mas também outros tipos de dados:
\n\n// Slice de structs\npeople := []Person{\n {Name: "Ana", Age: 25, City: "Rio"},\n {Name: "Pedro", Age: 35, City: "Belo Horizonte"},\n}\njsonBytes, _ := json.Marshal(people)\nfmt.Println(string(jsonBytes))\n// Saída: [{"Name":"Ana","Age":25,"City":"Rio"},{"Name":"Pedro","Age":35,"City":"Belo Horizonte"}]\n\n// Map\nscores := map[string]int{"Álgebra": 5, "Física": 4, "Informática": 5}\njsonBytes, _ = json.Marshal(scores)\nfmt.Println(string(jsonBytes))\n// Saída: {"Álgebra":5,"Física":4,"Informática":5}\n\nParsing JSON: convertendo JSON para estruturas Go
\n\nParsing (desserialização) é o processo inverso: a partir de uma string JSON, obtemos uma estrutura Go. Para isso, utiliza-se a função json.Unmarshal().
Parsing em uma struct
\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":"João Silva","Age":30,"City":"São Paulo"}`\n\n var person Person\n err := json.Unmarshal([]byte(jsonString), &person)\n if err != nil {\n fmt.Println("Erro de parsing:", err)\n return\n }\n\n fmt.Printf("Nome: %s, Idade: %d, Cidade: %s\\n", person.Name, person.Age, person.City)\n // Saída: Nome: João Silva, Idade: 30, Cidade: São Paulo\n}\n\nImportante: passe um ponteiro para a struct (&person), caso contrário, Unmarshal não conseguirá modificar seus campos.
Parsing em map[string]interface{}
\n\nSe a estrutura de dados não for conhecida antecipadamente, pode-se usar um tipo genérico:
\n\njsonString := `{"name":"Ana","