---
title: "Go JSON Evolui: Uma Nova API Experimental para o Futuro"
url: "https://golang.com.br/blog/go-json-nova-api-experimental/"
markdown_url: "https://golang.com.br/blog/go-json-nova-api-experimental.MD"
description: "Nova API experimental encoding/json/v2 em Go resolve problemas de 15 anos do pacote JSON original. Conheça as melhorias de comportamento, API e performance."
date: "2025-09-09"
author: "Go Blog (Resumo)"
---

# Go JSON Evolui: Uma Nova API Experimental para o Futuro

Nova API experimental encoding/json/v2 em Go resolve problemas de 15 anos do pacote JSON original. Conheça as melhorias de comportamento, API e performance.


O artigo do blog oficial do Go anuncia o lançamento de uma nova API experimental para JSON, presente nos pacotes `encoding/json/v2` e `encoding/json/jsontext`, com o objetivo de abordar as limitações e problemas existentes no pacote `encoding/json` (denominado `v1` neste contexto).  Após quase 15 anos desde a introdução do suporte a JSON em Go, e com o JSON se tornando o formato de dados mais popular na internet, a equipe de desenvolvimento do Go reconheceu a necessidade de evoluir o pacote padrão para atender às demandas modernas e corrigir falhas identificadas ao longo do tempo.

## Problemas Identificados no `encoding/json` (v1)

O artigo detalha uma série de problemas com o pacote `encoding/json` original, categorizados em falhas de comportamento, deficiências na API e limitações de desempenho.

### Falhas de Comportamento

*   **Manipulação Imprecisa da Sintaxe JSON:** O `encoding/json` é permissivo com relação a sintaxes JSON inválidas.
    *   Aceita UTF-8 inválido, enquanto o padrão mais recente (RFC 8259) exige UTF-8 válido. Isso pode levar a corrupção silenciosa de dados.
    *   Aceita objetos com nomes de membros duplicados, o que pode levar a comportamentos inesperados e até mesmo vulnerabilidades de segurança.  A RFC 8259 não especifica como lidar com nomes duplicados, deixando a implementação a cargo do interpretador JSON.  Isso pode resultar em diferentes interpretações do mesmo JSON por diferentes sistemas, um risco explorado em ataques como o CVE-2017-12635.
*   **Vazamento da "nulidade" de slices e maps:** `encoding/json` serializa slices e maps nulos como `null` em JSON.  Isso pode causar problemas de interoperabilidade com sistemas que não aceitam `null` para arrays ou objetos.  A maioria dos usuários Go prefere que slices e maps nulos sejam serializados como arrays ou objetos vazios por padrão.
*   **Unmarshaling Insensível ao Caso:** A correspondência entre nomes de membros JSON e campos de structs Go é feita de forma *case-insensitive*. Isso é um comportamento surpreendente, pode ser uma vulnerabilidade de segurança e limita o desempenho.
*   **Chamadas Inconsistentes de Métodos:** Métodos `MarshalJSON` definidos em um receptor ponteiro são chamados de forma inconsistente pelo `encoding/json` devido a detalhes de implementação. Embora seja considerado um bug, não pode ser corrigido devido à dependência de muitas aplicações no comportamento atual.

### Deficiências na API

*   **Dificuldade em Unmarshaling de um `io.Reader`:**  É difícil garantir que não haja "lixo" (trailing data) após um valor JSON válido ao deserializar de um `io.Reader` usando `json.NewDecoder(r).Decode(v)`.
*   **Opções Limitadas:** As opções definidas nos tipos `Encoder` e `Decoder` não podem ser usadas com as funções `Marshal` e `Unmarshal`. Da mesma forma, tipos que implementam as interfaces `Marshaler` e `Unmarshaler` não podem usar as opções, criando uma inconsistência na aplicação de configurações. Por exemplo, a opção `Decoder.DisallowUnknownFields` perde o efeito ao chamar um método `UnmarshalJSON` personalizado.
*   **Funções de Formatação Limitadas:** As funções `Compact`, `Indent` e `HTMLEscape` gravam em um `bytes.Buffer` em vez de uma interface mais flexível como `[]byte` ou `io.Writer`, o que limita sua usabilidade.

### Limitações de Desempenho

*   **MarshalJSON:** A interface `MarshalJSON` força a alocação de um `[]byte` retornado. Além disso, o `encoding/json` deve verificar se o resultado é JSON válido e reformatá-lo para corresponder à indentação especificada.
*   **UnmarshalJSON:** A interface `UnmarshalJSON` requer um valor JSON completo (sem dados extras). Isso força o `encoding/json` a analisar o valor JSON a ser deserializado por completo para determinar onde termina antes de chamar `UnmarshalJSON`. Depois, o método `UnmarshalJSON` em si deve analisar o valor JSON fornecido novamente.
*   **Falta de Streaming:** Embora os tipos `Encoder` e `Decoder` operem em um `io.Writer` ou `io.Reader`, eles armazenam em buffer o valor JSON inteiro na memória. O método `Decoder.Token` para ler tokens individuais é pesado em alocação, e não há uma API correspondente para escrever tokens.

Além disso, se a implementação de um método `MarshalJSON` ou `UnmarshalJSON` chama recursivamente a função `Marshal` ou `Unmarshal`, o desempenho se torna quadrático.

## A Necessidade de uma Nova Versão (v2)

O artigo explica que, embora a equipe de desenvolvimento tenha considerado corrigir o pacote `encoding/json` diretamente, as limitações da API existente e a promessa de compatibilidade do Go 1 tornaram isso impraticável.  A introdução de uma nova versão principal (v2) permite quebrar a compatibilidade com a versão anterior e introduzir as mudanças necessárias para resolver os problemas identificados.

A alternativa de criar funções separadas, como `MarshalV2` ou `UnmarshalV2`, foi considerada, mas descartada por ser equivalente a criar um namespace paralelo dentro do mesmo pacote. A solução encontrada foi criar o pacote `encoding/json/v2`, que oferece um novo namespace onde as mudanças podem ser feitas sem afetar a compatibilidade com o `encoding/json` original (v1).

## Planejamento do `encoding/json/v2`

O planejamento para a nova versão do `encoding/json` levou anos. Em 2020, a impossibilidade de corrigir os problemas no pacote existente impulsionou Daniel Martí a elaborar um documento sobre como seria um pacote `v2` hipotético. Joe Tsai, após trabalhar na API do Go para Protocol Buffers, percebeu que o pacote `protojson` precisava usar uma implementação JSON personalizada, pois o `encoding/json` não era capaz de aderir ao padrão JSON mais rigoroso exigido pela especificação do Protocol Buffer, nem de serializar JSON de forma eficiente em streaming.

Daniel e Joe uniram forças para criar um protótipo para o `v2`, com o código inicial sendo uma versão aprimorada da lógica de serialização JSON do módulo Go protobuf. Ao longo do tempo, outros (Roger Peppe, Chris Hines, Johan Brandhorst-Satzkorn e Damien Neil) se juntaram ao esforço, fornecendo revisão de design, revisão de código e testes de regressão.

## O Novo Pacote `encoding/json/v2`

O artigo não entra em detalhes específicos sobre a nova API, mas implicitamente sugere que ela abordará os problemas mencionados acima:

*   **Sintaxe JSON Mais Estrita:** A nova API deve ser mais rigorosa na validação da sintaxe JSON, rejeitando UTF-8 inválido e objetos com nomes de membros duplicados.
*   **Controle da "Nulidade":** A nova API provavelmente oferecerá opções para controlar como slices e maps nulos são serializados (como `null` ou como arrays/objetos vazios).
*   **Unmarshaling Sensível ao Caso:** A nova API provavelmente usará *case-sensitive* por padrão.
*   **API Mais Consistente:** A nova API deve ter uma API mais consistente, com opções que podem ser usadas com todas as funções de marshaling e unmarshaling, e a capacidade de passar opções para métodos `MarshalJSON` e `UnmarshalJSON` personalizados.
*   **Melhor Desempenho:** A nova API pode oferecer suporte a streaming para reduzir o uso de memória e evitar a necessidade de analisar o JSON várias vezes.

## O Pacote `encoding/jsontext`

O artigo também menciona o pacote `encoding/jsontext`, que provavelmente lida com a representação textual de JSON e pode oferecer funcionalidades adicionais relacionadas à manipulação de texto JSON.  Detalhes específicos sobre este pacote não são fornecidos no texto.

## Status Experimental e Próximos Passos

É crucial notar que os pacotes `encoding/json/v2` e `encoding/jsontext` são experimentais e podem sofrer alterações na API no futuro. O objetivo é coletar feedback da comunidade e refinar a API antes de torná-la estável.

Para usar os pacotes experimentais, é necessário importá-los explicitamente:

```go
import "encoding/json/v2"
import "encoding/json/jsontext"
```

A equipe de desenvolvimento incentiva os usuários a experimentar a nova API e fornecer feedback para ajudar a moldar o futuro do JSON em Go.

Em resumo, o lançamento dos pacotes `encoding/json/v2` e `encoding/jsontext` representa um passo importante na evolução do suporte a JSON em Go, visando resolver problemas de longa data e fornecer uma API mais moderna, flexível e eficiente. A fase experimental é fundamental para garantir que a nova API atenda às necessidades da comunidade Go e se torne um padrão robusto para o futuro.

---

## Artigo Original

Este e um resumo em português do artigo original publicado no blog oficial do Go.

**Titulo original:** A new experimental Go API for JSON

[Leia o artigo completo em ingles no Go Blog](https://go.dev/blog/jsonv2-exp)

*Autor original: Joe Tsai, Daniel Martí, Johan Brandhorst-Satzkorn, Roger Peppe, Chris Hines, and Damien Neil*
