Processamento de JSON em Go (Golang): do básico às técnicas avançadas
Go (Golang) oferece um conjunto poderoso e intuitivo de ferramentas para trabalhar com JSON. A biblioteca padrão encoding/json cobre 95% das tarefas, e para projetos de alta carga existem alternativas mais performáticas. Neste artigo, abordaremos todos os aspectos do processamento de JSON em Go: desde a serialização básica até analisadores personalizados e otimização.
1. Fundamentos: biblioteca padrão encoding/json
Em Go, o JSON é processado através do pacote encoding/json. As operações principais são marshaling (serialização para JSON) e unmarshaling (desserialização de JSON).
1.1. Marshaling (struct → JSON)
Para converter uma estrutura Go em JSON, utiliza-se a função 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 - pular se vazio}
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"}}Importante: Os campos da estrutura devem ser exportáveis (com letra maiúscula). As tags json:"fieldname" controlam a nomeação dos campos no JSON.
1.2. Unmarshaling (JSON → struct)
Para a conversão inversa, utiliza-se json.Unmarshal():
func main() { jsonString := `{"name":"Ana","age":25,"email":"ana@mail.com"}` var user User err := json.Unmarshal([]byte(jsonString), &user) if err != nil { log.Fatal(err) }
fmt.Printf("Nome: %s, Idade: %d", user.Name, user.Age) // Nome: Ana, Idade: 25}2. Trabalhando com estruturas aninhadas e arrays
O JSON frequentemente contém objetos e arrays aninhados. Em Go, isso é mapeado para estruturas e slices aninhados:
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": "Rua Tverskaya, 10", "zip_code": "101000" } }`
var company Company json.Unmarshal([]byte(companyJSON), &company) fmt.Printf("Empresa: %s, Cidade: %s, Funcionários: %d", company.Name, company.Address.City, len(company.Employees))}3. Técnicas avançadas
3.1. Serialização personalizada (interfaces Marshaler/Unmarshaler)
Às vezes é necessário controlar como um tipo é convertido para JSON. Para isso, implementam-se as interfaces json.Marshaler e 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 Também na biblioteca
Filas de tarefas para TypeScript: Bull, Agenda e Bee-Queue
Sarama para Go: guia completo com exemplos
Trabalho com arquivos ZIP em Go (Golang): criação, leitura e extração de arquivos
Métricas Prometheus em C# (.NET): integração e configuração
Geração Swagger/OpenAPI para C++: melhores ferramentas e bibliotecas