Por que o JSON em Go parece uma bagunça e como corrigir isso?
\nVocê já escreveu um programa em Go que exibe JSON e obteve no terminal algo assim?
\n{"name":"PythonLib","year":2025,"tags":["go","json","tutorial"],"active":true}\nConcordo, ler isso sem ferramentas especiais não é nada agradável. Especialmente quando a estrutura de dados é complexa e o aninhamento vai a vários níveis. Os olhos começam a se perder e encontrar o campo desejado se torna uma verdadeira missão.
\nA boa notícia: o Go possui ferramentas nativas que transformam essa "bagunça" em um documento organizado e estruturado. E hoje vamos analisar todas as formas de formatar JSON de forma bonita — desde o uso simples da biblioteca padrão até a criação de sua própria ferramenta de pretty-print.
\nEste material é baseado em uma pergunta real do Stack Overflow (mais de 50.000 visualizações), então o tema é realmente relevante. Vamos nessa!
\n\nO que é pretty-print e para que serve?
\nPretty-print (ou "impressão bonita") é a formatação de dados com recuos, quebras de linha e alinhamento para facilitar a leitura humana. No contexto do JSON, isso significa:
\n- \n
- Adicionar espaços ou tabulações para elementos aninhados \n
- Quebrar cada par "chave-valor" em uma nova linha \n
- Alinhar valores para melhor visualização \n
Para que isso serve em Go? Imagine que você está depurando uma resposta de API, escrevendo um logger ou apenas exibindo uma configuração. O JSON não formatado ocupa menos espaço, mas é completamente ilegível. O pretty-print resolve esse problema com algumas linhas de código.
\n\nMétodo 1: json.MarshalIndent — solução padrão
\nA maneira mais simples e recomendada é usar a função json.MarshalIndent do pacote padrão encoding/json. Ela faz exatamente o que é necessário: recebe os dados e retorna o JSON formatado com recuos.
Aqui está um exemplo básico:
\npackage main\n\nimport (\n "encoding/json"\n "fmt"\n "log"\n)\n\ntype Site struct {\n Name string `json:"name"`\n Year int `json:"year"`\n Tags []string `json:"tags"`\n Active bool `json:"active"`\n}\n\nfunc main() {\n site := Site{\n Name: "PythonLib",\n Year: 2025,\n Tags: []string{"go", "json", "tutorial"},\n Active: true,\n }\n\n // Prefixo — "", recuo — " " (dois espaços)\n prettyJSON, err := json.MarshalIndent(site, "", " ")\n if err != nil {\n log.Fatalf("Erro de marshaling: %v", err)\n }\n\n fmt.Println(string(prettyJSON))\n}\nResultado:
\n{\n "name": "PythonLib",\n "year": 2025,\n "tags": [\n "go",\n "json",\n "tutorial"\n ],\n "active": true\n}\nBonito, não é? Observe o segundo e terceiro parâmetros do MarshalIndent:
- \n
- Prefixo — string adicionada ao início de cada linha. Geralmente uma string vazia
"". \n - Recuo — string para cada nível de aninhamento. Mais comumente usam-se dois espaços
" "ou tabulação"\\t". \n
Configuração de recuos: espaços vs tabulação
\nVocê pode facilmente alterar o estilo dos recuos. Por exemplo, com tabulação:
\nprettyJSON, _ := json.MarshalIndent(site, "", "\\t")\nfmt.Println(string(prettyJSON))\nResultado:
\n{\n\t"name": "PythonLib",\n\t"year": 2025,\n\t"tags": [\n\t\t"go",\n\t\t"json",\n\t\t"tutorial"\n\t],\n\t"active": true\n}\nQual opção escolher? Se o seu projeto segue os padrões do Go (que recomendam tabulação para código), use "\\t". Se você trabalha em uma equipe onde espaços são a norma, dois espaços serão mais adequados. O importante é a consistência.
Método 2: Pretty-print para strings JSON brutas
\nE se você já tiver uma string com JSON não format