JSON para Go
Analise JSON e gere automaticamente definições de struct Go com nomes de campos em PascalCase e tags json para integração fluida no seu código Go.
Entrada & saída
Opções
Como funciona
- Cole seu JSON : insira qualquer objeto JSON ou estrutura aninhada no campo de entrada.
- Obtenha a struct Go : a definição equivalente de struct Go com nomes de campos, tipos e tags JSON corretos é gerada instantaneamente.
- Copie e use : copie o código da struct e cole-o no seu projeto Go para começar a desserializar dados JSON.
Por que usar o conversor JSON → struct Go ?
Escrever structs Go manualmente para respostas JSON complexas é tedioso e sujeito a erros, especialmente quando a API retorna objetos profundamente aninhados com dezenas de campos. JSON → Go automatiza isso analisando a forma do JSON e gerando structs Go corretamente tipadas com tags json:"…" apropriadas, correspondendo aos nomes de campos JSON. Isso acelera o desenvolvimento Go ao consumir APIs REST, processar cargas úteis de webhook ou trabalhar com qualquer fonte de dados JSON.
Funcionalidades
- Geração de structs aninhadas : objetos JSON profundamente aninhados são convertidos em definições de structs Go aninhadas.
- Inferência de tipos : strings, números, booleanos, arrays e valores null são associados aos tipos Go apropriados.
- Tags JSON : todos os campos incluem tags de struct json:"fieldName" correspondendo às chaves JSON originais.
- Gestão de arrays : os arrays JSON viram slices Go com o tipo de elementos correto.
- Tipos ponteiros : os campos JSON nullable são representados por tipos ponteiros (por exemplo, *string).
Perguntas frequentes
Como os valores null são tratados ?
Os campos JSON null são convertidos em tipos ponteiros em Go (por exemplo, *string, *int), o que permite representar tanto nil quanto um valor real. Isso lida corretamente com campos opcionais ou nullable na resposta da API.
E se o JSON tiver tipos inconsistentes ?
Se o mesmo campo aparece com tipos diferentes entre os objetos JSON (frequente em APIs reais), o conversor pode inferir interface{} (any no Go moderno). Revise esses campos e adicione assertivas de tipos personalizadas conforme necessário.
Ele gera o código de desserialização completo ?
A ferramenta gera as definições de structs. Para desserializar, use json.Unmarshal(data, &myStruct) ou json.NewDecoder(r.Body).Decode(&myStruct) com o pacote encoding/json padrão.
Breve história de Go e JSON
Go foi anunciado no Google por Rob Pike, Robert Griesemer e Ken Thompson em novembro de 2009; o pacote encoding/json chegou à biblioteca padrão antes de Go 1.0 (março de 2012). O parsing JSON em Go é baseado em reflexão: você declara uma struct, etiqueta os campos com json:"name", e json.Unmarshal percorre tanto a struct quanto os bytes. O padrão se mostrou tão produtivo que escrever structs à mão para grandes APIs se tornou tedioso rapidamente. Mat Ryer construiu mholt/json-to-go como uma ferramenta apenas JavaScript em 2014 (ainda é mantida em mholt.github.io/json-to-go) usando parsing JSON baseado em regex no navegador. quicktype (David Siegel, 2017) generalizou a ideia para 23 linguagens incluindo TypeScript, Rust, Swift, Kotlin, Python, Java. O focado em desempenho easyjson (Mail.ru, 2016) pula a reflexão gerando código de marshalling em tempo de compilação, 4-5× mais rápido que encoding/json para caminhos quentes. Go 1.18 (março de 2022) adicionou genéricos, que simplificaram alguns helpers de marshalling mas não mudaram o idioma de tags de struct. Go 1.21 (agosto de 2023) adicionou o pacote experimental encoding/json/v2 (proposta ainda em discussão em 2024), visando corrigir armadilhas antigas como incompatibilidades silenciosas de tipo e reflexão lenta.
Struct vs map[string]interface{}: quando cada um faz sentido
- Structs tipadas vencem para formas conhecidas. Se você controla a API ou tem um schema estável, structs dão verificação de campo em tempo de compilação, autocomplete da IDE e parsing 2-3× mais rápido.
json.Unmarshalem uma struct toca apenas campos que reconhece, ignorando chaves JSON desconhecidas silenciosamente (a menos que você chamedecoder.DisallowUnknownFields). - Maps vencem para JSON arbitrário.
map[string]interface{}(ou em Go 1.18+map[string]any) lida com formas selvagemente variáveis, payloads de webhook de muitas fontes, configurações de plugins, documentos MongoDB. Trade-off: cada acesso precisa de uma assertion de tipo (data["age"].(float64)), e números são parseados comofloat64por padrão, perdendo precisão para inteiros grandes. - Híbrido: campos conhecidos como struct, desconhecidos como map. Use
json.RawMessagepara adiar o parsing ou adicione um campo catch-allExtra map[string]interface{} `json:"-,inline"`(com ajuda de bibliotecas comogo-restful). Os SDKs Go de Stripe e Twilio usam esse padrão para respostas API com compatibilidade futura. - Lacuna de desempenho. Caminhos quentes (por exemplo, parsear 10.000 eventos webhook por segundo) se beneficiam de marshallers gerados:
easyjson,ffjson,go-json,sonic(ByteDance, 2022, usa JIT para gerar código de máquina em runtime, biblioteca JSON mais rápida em Go). Parsing genérico baseado em struct lida com talvez 100-200 MB/s;soniclida com 1-2 GB/s. - Streaming para JSON enorme. Um arquivo JSON de 1 GB não cabe na memória.
json.Decoder.Token()lê token por token.json.Decoder.More()percorre elementos de array um por vez. Use streaming para arquivos de log, datasets grandes, streams ND-JSON (um objeto JSON por linha, usado por OpenSearch, BigQuery, API do ChatGPT).
Onde a conversão JSON para Go economiza tempo real
- Integração de API REST. Stripe, GitHub, Slack, Notion todos retornam JSON profundamente aninhado. Pegar uma resposta de amostra e colar no json-to-go produz 80-90% da struct final. Gaste o tempo economizado nos 10% (unmarshallers personalizados para formatos de tempo, semântica omitempty, campos ponteiro opcionais).
- Handlers de webhook. Um payload webhook Stripe típico tem 80-200 campos com 3-5 níveis de aninhamento. Digitar à mão a struct Go leva 30-60 minutos; colar o payload de amostra através do json-to-go leva 30 segundos.
- Parsing de configuração. Arquivos de configuração JSON (preferidos sobre TOML pelo AWS Lambda, Docker Compose
compose.json, devcontainer.json) mapeiam limpamente para structs Go.encoding/jsonlida tanto com leitura quanto escrita do arquivo com a mesma struct. - Pontes gRPC e Protobuf. Tipos Go protobuf gerados incluem tags
json. Ao transcodificar entre protobuf e JSON (gRPC-Gateway, Buf, Connect), json-to-go ajuda a esboçar o lado Go a partir do formato wire JSON. - Colunas JSONB de banco de dados. PostgreSQL
jsonb, documentos MongoDB, colunas JSON do MySQL. O driverdatabase/sqlretorna[]byteque você unmarshala em uma struct. Geradores aceleram a primeira passagem para tabelas schema-on-read. - Dados de fixture para testes. Uma resposta JSON de produção real se torna a fixture de teste. json-to-go te dá a struct para unmarshalar para assertions. Combinado com diretórios
testdata/(convenção Go desde 1.10), mantém os testes próximos da realidade. - Pipelines CSV-para-JSON-para-struct. Para tarefas de engenharia de dados: ler CSV, marshalar como JSON para inspeção, colar no json-to-go para obter a struct, depois escrever um pipeline tipado. Muito mais rápido do que adivinhar tipos de coluna a partir de uma planilha.
Erros comuns após gerar structs
- Esquecer o tratamento de time.Time.
encoding/jsonassume formato RFC 3339 (2026-05-13T12:34:56Z). A maioria das APIs entrega isso mas algumas usam timestamps Unix (Stripe), ISO sem timezone (APIs Microsoft legadas), ou strings personalizadas. Para não-RFC-3339, defina um tipo personalizado com métodoUnmarshalJSON. - Overflow de inteiro com float64 padrão. Um número JSON parseado em
interface{}se tornafloat64; números acima de 2^53 perdem precisão. IDs de cliente Stripe, snowflake do Twitter, usuários do Discord (todos 64 bits) precisam dejson.Numberouint64na sua struct. Usejson.Decoder.UseNumber()para parsing seguro eminterface{}. - Mal-entender
omitempty.omitemptyomite o campo no marshal se for o valor zero (string vazia, 0, ponteiro nil, slice/map vazio). Não significa «opcional no unmarshal». Um campointcom valor 0 é indistinguível de faltante; use*intse você precisa saber se a API omitiu o campo ou enviou zero. - Incompatibilidades de caixa em nomes de campo. Campos Go devem ser exportados (capitalizados) para serem marshalados. O nome JSON padrão é o nome Go literalmente, então
UserIDse torna"UserID"em JSON a menos que esteja taggeado. Geradores adicionam tagsjson:"userId"para fazer a ponte entrePascalCasede Go comcamelCasede JSON. Esquecer a tag significa que seu código «funciona» consigo mesmo mas falha contra APIs externas. - Usar demais tipos ponteiro. Geradores às vezes usam
*stringou*intpor padrão por segurança. Isso faz cada acesso precisar de uma verificação nil. Se a API garante que o campo está sempre presente (leia a documentação da API), use o tipo valor e pule a indireção. - Tipos inconsistentes entre respostas. Algumas APIs retornam
tags: []string{"foo"}em uma resposta etags: "foo"como string em outra. Geração pura de código não pode fazer essa ponte. Escreva umUnmarshalJSONpersonalizado que lida com ambos os casos, ou mude parainterface{}e documente a variabilidade. - Descarte silencioso de campos desconhecidos. Por padrão,
json.Unmarshalignora chaves JSON não na struct. Isso é frequentemente um bug: a API adicionou um campo, seu código não sabe. Usedecoder.DisallowUnknownFields()em testes para capturar desvios; em produção mantenha-o permissivo.
Mais perguntas frequentes
Como isso difere do canônico mholt/json-to-go?
Mesmo algoritmo central: parsear o JSON, inferir tipos da primeira ocorrência de cada campo, gerar uma struct com campos taggeados entre crases. Esta implementação roda inteiramente no seu navegador sem analytics ou chamadas de rede; a canônica é hospedada em mholt.github.io/json-to-go, também apenas-navegador mas em um domínio diferente. A saída deve combinar para ~95% das entradas; casos extremos (arrays de tipos mistos, structs anônimas profundamente aninhadas) podem diferir ligeiramente. Se você precisa de uma saída mholt exata, use aquele; se precisa de garantias de privacidade de que o JSON nunca deixa seu dispositivo, use este.
Por que alguns campos são gerados como interface{}?
Três razões usuais. Primeiro, literal null no JSON fonte: o gerador não pode inferir um tipo útil só de null, então recorre a interface{}. Substitua por um ponteiro tipado (*string, *int) uma vez que você conhece o schema real. Segundo, arrays de tipos mistos: [1, "two", true] não pode ser um slice tipado. Terceiro, campo completamente faltante em sua amostra, cole um JSON mais representativo se disponível. No Go 1.18+ você pode substituir interface{} pelo apelido mais limpo any; eles são idênticos no nível de tipo.
Posso fazer ida e volta de JSON através desta struct sem perder dados?
Geralmente sim, com ressalvas. encoding/json preserva valores de campo mas não ordem de campo (a spec JSON diz que ordem de campo é irrelevante; maps Go são deliberadamente aleatórios). Precisão numérica: int64s acima de 2^53 fazem ida e volta seguramente como int64 Go, mas se você alguma vez fizer cast para float64 ou enviar através de JavaScript (por exemplo intermediário navegador) você perde dígitos. Campos JSON desconhecidos são descartados silenciosamente em unmarshal-então-remarshal, preserve-os com um catch-all map[string]json.RawMessage se a fidelidade de ida e volta importa.
Quando devo usar código struct gerado (easyjson, sonic) em vez de encoding/json?
Padrão para encoding/json: é bom o suficiente para 95% dos serviços e vem com a linguagem. Mude para easyjson ou sonic quando você profilou e o marshalling JSON aparece no seu flame graph de CPU com >10% do tempo total. Pontos típicos de quebra: serviços HTTP lidando com milhares de requisições por segundo, agregadores de log ingerindo GBs/hora, feeds em tempo real. Ambas as alternativas mantêm as mesmas definições de struct e tags, então você pode trocá-las sem mudar as declarações de campo.
Meu JSON é enviado para algum servidor?
Não. O parsing JSON e a geração de código Go ambos rodam em JavaScript no seu dispositivo. Abra a aba Network no DevTools enquanto cola; você verá zero requisições saintes. Seguro para respostas de API proprietárias, fixtures de dados de clientes, payloads webhook com PII, e qualquer outra coisa coberta por NDA.