Trabalhando com JSON em Go: parsing e serialização na prática
JSON (JavaScript Object Notation) é um dos formatos de troca de dados mais populares no desenvolvimento web. Na linguagem Go (Golang), o trabalho com JSON é implementado através do pacote padrão encoding/json, que fornece ferramentas poderosas e convenientes para serialização (conversão de estruturas de dados em JSON) e desserialização (parsing de JSON em estruturas Go). Neste artigo, vamos detalhar como trabalhar com JSON em Go com exemplos práticos.
Fundamentos: serialização de estruturas em JSON
A forma mais comum de trabalhar com JSON em Go é usando estruturas com tags. As tags permitem definir nomes de campos em JSON que podem ser diferentes dos nomes dos campos em Go. Vejamos um exemplo básico de serialização:
package main
import ( "encoding/json" "fmt")
type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` IsActive bool `json:"is_active"`}
func main() { user := User{ ID: 1, Name: "João Silva", Email: "joao@example.com", IsActive: true, }
jsonData, err := json.Marshal(user) if err != nil { fmt.Println("Erro de serialização:", err) return }
fmt.Println(string(jsonData)) // Saída: {"id":1,"name":"João Silva","email":"joao@example.com","is_active":true}}Observe: usamos tags json:"nome_do_campo" para controlar os nomes das chaves no JSON. Isso é especialmente útil quando é necessário seguir padrões de nomenclatura específicos (por exemplo, snake_case no JSON e CamelCase em Go).
Parsing de JSON em estruturas Go
A desserialização (parsing) de dados JSON em estruturas é feita com a função json.Unmarshal. É importante que a estrutura corresponda à estrutura do objeto JSON. Continuando com nosso exemplo:
func main() { jsonString := `{"id":2,"name":"Maria Santos","email":"maria@example.com","is_active":false}`
var user User err := json.Unmarshal([]byte(jsonString), &user) if err != nil { fmt.Println("Erro de parsing:", err) return }
fmt.Printf("ID: %d, Nome: %s, Email: %s, Ativo: %t", user.ID, user.Name, user.Email, user.IsActive) // Saída: ID: 2, Nome: Maria Santos, Email: maria@example.com, Ativo: false}Importante: Na função json.Unmarshal sempre é passado um ponteiro para a estrutura (&user), caso contrário as alterações não serão salvas.
Trabalhando com estruturas aninhadas e arrays
Dados JSON reais frequentemente contêm objetos aninhados e arrays. Go permite lidar elegantemente com esses casos usando estruturas aninhadas:
type Address struct { City string `json:"city"` Street string `json:"street"` ZipCode string `json:"zip_code"`}
type Employee struct { ID int `json:"id"` Name string `json:"name"` Skills []string `json:"skills"` Address Address `json:"address"`}
func main() { jsonData := `{ "id": 101, "name": "Alexei Ivanov", "skills": ["Go", "Python", "Docker"], "address": { "city": "Moscou", "street": "Tverskaya, 10", "zip_code": "101000" } }`
var emp Employee err := json.Unmarshal([]byte(jsonData), &emp) if err != nil { fmt.Println("Erro:", err) return }
fmt.Printf("Funcionário: %s, Cidade: %s, Habilidades: %v", emp.Name, emp.Address.City, emp.Skills) // Saída: Funcionário: Alexei Ivanov, Cidade: Moscou, Habilidades: [Go Python Docker]}Para arrays em Go, usamos slices ([]string), e para objetos aninhados, estruturas separadas. Ao fazer parsing de um array JSON de objetos, é poss