Trabalhando com JSON em Go: parsing e serialização de dados

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
Here is the translated HTML content in Portuguese (Português), with all HTML tags preserved and only the text content translated. ```html

Introdução ao trabalho com JSON em Go

JSON (JavaScript Object Notation) é um formato leve de troca de dados, amplamente utilizado em aplicações web, APIs e microsserviços. A linguagem Go (Golang) fornece uma poderosa biblioteca embutida encoding/json, que permite realizar facilmente parsing (desserialização) e serialização de dados. Neste artigo, vamos detalhar como trabalhar com JSON em Go, abordando as principais funções, estruturas e melhores práticas.

Fundamentos de serialização e desserialização

Serialização é o processo de converter uma estrutura de dados do Go (por exemplo, uma struct ou slice) em uma string JSON. Desserialização é a conversão inversa, de JSON para uma estrutura do Go.

Serialização (Marshal)

Para serialização, utiliza-se a função json.Marshal(). Ela recebe um valor Go e retorna um slice de bytes ([]byte) com a representação JSON.

package main

import (
    "encoding/json"
    "fmt"
)

type User struct {
    Name  string `json:"name"`
    Age   int    `json:"age"`
    Email string `json:"email,omitempty"`
}

func main() {
    user := User{Name: "Alexey", Age: 30, Email: "alex@example.com"}
    jsonData, err := json.Marshal(user)
    if err != nil {
        fmt.Println("Erro de serialização:", err)
        return
    }
    fmt.Println(string(jsonData))
    // Saída: {"name":"Alexey","age":30,"email":"alex@example.com"}
}

Observe as tags json:"nome_do_campo". Elas permitem controlar os nomes das chaves no JSON, além de adicionar opções como omitempty (pular o campo se estiver vazio).

Desserialização (Unmarshal)

Para fazer o parsing de JSON para uma estrutura Go, utiliza-se a função json.Unmarshal(). Ela recebe um slice de bytes e um ponteiro para a estrutura onde os dados devem ser armazenados.

func main() {
    jsonString := `{"name":"Maria","age":25,"email":"maria@example.com"}`
    var user User
    err := json.Unmarshal([]byte(jsonString), &user)
    if err != nil {
        fmt.Println("Erro de parsing:", err)
        return
    }
    fmt.Printf("Nome: %s, Idade: %d, Email: %s", user.Name, user.Age, user.Email)
}

Importante: a estrutura deve ser predefinida, e seus campos devem corresponder às chaves JSON (considerando as tags).

Trabalhando com objetos JSON arbitrários

Às vezes, a estrutura do JSON é desconhecida antecipadamente ou muito complexa. Nesses casos, pode-se usar map[string]interface{} ou interface{}.

Usando map[string]interface{}

func main() {
    jsonString := `{"name":"Ivan","age":35,"address":{"city":"Moscou","street":"Lenina"}}`
    var result map[string]interface{}
    err := json.Unmarshal([]byte(jsonString), &result)
    if err != nil {
        fmt.Println("Erro:", err)
        return
    }
    fmt.Println(result["name"]) // Ivan
    fmt.Println(result["age"])  // 35 (tipo float64)
    // Para objetos aninhados, é necessário fazer type assertion
    address := result["address"].(map[string]interface{})
    fmt.Println(address["city"]) // Moscou
}

A desvantagem dessa abordagem é a necessidade de conversão manual de tipos (.(map[string]interface{})), o que pode causar pânico se os tipos não coincidirem.

Usando json.RawMessage

Se for necessário adiar o parsing de parte do JSON, use json.RawMessage. Isso permite primeiro analisar a estrutura principal e depois processar os dados aninhados separadamente.

type Response struct {
    Status string          `json:"status"`
    Data   json.RawMessage `json:"data"`
}

func main() {
    jsonString := `{"status":"ok","data":{"user":"Pedro","score":100}}`
    var resp Response
    json.Unmarshal([]byte(jsonString), &resp)

    // Agora é possível analisar Data separadamente
    var userData map[string]interface{}
    json.Unm
```                

Blogs

Book Recommendations