ToolActToolAct
O que é JSON?

O que é JSON?

Vida Prática3 de ago. de 202615 min de leitura

Tudo começa com uma requisição de rede

Uma cena que você provavelmente conhece. Você está com o DevTools aberto, na aba Network, e acabou de clicar num botão do sistema interno da empresa. O servidor responde. Você expande a linha da requisição e olha a aba Preview. Não é HTML, não é aquele XML cheio de tags que a gente via nos anos 2000. É uma parede de texto composta por chaves, colchetes, aspas duplas e vírgulas. Algo assim:

{"status":"ok","data":{"user":{"id":42,"name":"Mariana","roles":["admin","reports"]}}}

Em menos de um segundo você sabe o que isso significa. Não precisa de documentação, não precisa de um schema, não precisa de uma folha de transformação. Você lê o texto e o texto faz sentido. É isso que o JSON faz de melhor: ele some na frente de você, deixa o dado aparecer como se não houvesse um formato no caminho.

Outra versão da mesma cena: dois sistemas conversando. Um serviço de pedidos, escrito em Java, manda uma mensagem. Um serviço de estoque, escrito em Python, recebe e processa. Nenhum dos dois se importa com a linguagem do outro. O que importa é aquele envelope de texto que os dois sabem abrir. O JSON é essa língua comum — não porque alguém escolheu o melhor formato possível, mas porque é a língua que todo mundo resolveu falar.

Depois de vinte e poucos anos, é o formato que está em quase toda resposta HTTP que não é HTML. E o mais curioso de tudo: ninguém abraçou o JSON por amor. Ele venceu por exaustão.

O que é o JSON, de verdade

JSON é JavaScript Object Notation. Vamos ser honestos sobre o nome: é um nome meio azarado. A sintaxe nasce dos object literals do JavaScript, é verdade — a forma como o JavaScript escreve objetos com {chave: valor}. Douglas Crockford pegou essa ideia, em algum momento de 2001, e isolou as partes que faziam sentido para troca de dados entre sistemas. O resultado virou uma página na json.org com duas frases e um diagrama. Esse era o formato.

Mas o JSON não tem nada a ver com o JavaScript, além desse parentesco de sintaxe. Você pode (e vai) usar JSON em Python, Java, Go, Rust, C, em sistemas que não tocam em JavaScript há uma década. O nome fica, porque renomear um padrão que já rodou o mundo é mais trabalho do que aguentar um nome ruim. E o "Notation" do nome também merece respeito: a ideia era descrever a notação, não criar uma linguagem nem uma biblioteca. Só o formato, nu.

Hoje a especificação vive em dois lugares. A ECMA-404 é publicada pela Ecma International, a mesma organização que padroniza o ECMAScript. E a RFC 8259, publicada em 2017, é a versão da IETF — ela substituiu a RFC 7159, que por sua vez substituiu a RFC 4627, de 2006. Se você está começando agora, leia a 8259 e pare por aí; a parte que importa cabe em poucas páginas.

O que o JSON é, no fundo: uma notação para representar dados que tanto um humano quanto uma máquina conseguem ler. Um humano abre um arquivo JSON e entende a estrutura em segundos — a hierarquia, os campos, os valores. Uma máquina faz o parse sem ambiguidade, sem espaço para adivinhar. Esse equilíbrio — simples o bastante para o cérebro humano, preciso o bastante para o computador — é o segredo de tudo.

Por que ele venceu o XML

Antes do JSON, o mundo trocava dados com XML. E não era um mundo bonito.

Tem gente que nem lembra mais da era SOAP: serviços web que exigiam WSDL para descrever o contrato, namespaces para evitar colisão de nomes, XSD para validar, e XSLT para transformar um XML em outro XML. Para ler uma resposta, você precisava de uma biblioteca de XML, um schema, e às vezes uma folha de transformação só para entender o que tinha vindo. Arquivos de configuração pareciam listas telefônicas, com tags de abertura e fechamento por toda parte.

Vamos ser justos: o XML tinha razão de existir. Documentos com metadados, marcadores e hierarquia — para isso ele era ótimo. O problema é que ele foi usado para tudo, inclusive para as coisas que não precisavam de metade daquela parafernália. Um pedaço de XML típico:

<?xml version="1.0" encoding="UTF-8"?>
<response>
  <status>ok</status>
  <data>
    <user id="42">
      <name>Mariana</name>
      <roles>
        <role>admin</role>
        <role>reports</role>
      </roles>
    </user>
  </data>
</response>

Agora a mesma informação em JSON:

{
  "status": "ok",
  "data": {
    "user": {
      "id": 42,
      "name": "Mariana",
      "roles": ["admin", "reports"]
    }
  }
}

Menos texto, menos tags de fechamento, menos barulho. Mas a vitória do JSON não é só tamanho. É que ele mapeia um-a-um sobre estruturas de dados que toda linguagem já tem. Um objeto vira um dicionário, um mapa, um hash. Uma array vira uma lista. String vira string, número vira número, booleano vira booleano, null vira null. Não existe a dúvida que atormentava o XML: isso é atributo ou elemento? Preciso de schema para entender? Cadê o namespace?

O XML forçava debates filosóficos — atributos versus elementos, XSD versus DTD, como representar uma lista vazia. JSON não tem debate nenhum. Ele é só dados.

E tem o detalhe do schema. XML sem schema é quase inútil para interoperar, porque a tag <name> pode significar qualquer coisa — é uma string, mas qual a estrutura? JSON carrega o tipo junto: "name":"Mariana" é uma string, e pronto. Você entende o documento sem consultar nenhum XSD.

Não é que o JSON seja bonito. É que tudo o mais era mais chato. E "menos chato" é um critério de seleção poderoso demais para subestimar. A maioria das tecnologias que vencem não vence por ser a melhor — vence por ser a que menos incomoda quando você está tentando terminar o trabalho.

Os seis tipos de dados

O JSON tem exatamente seis tipos. Nada mais, nada menos. Esse minimalismo é intencional: são os tipos que quase toda linguagem de programação tem, e por isso o mapeamento entre JSON e a sua linguagem é direto.

  • Objeto — uma coleção de pares chave→valor, entre chaves {}. A chave é sempre uma string entre aspas duplas; o valor pode ser qualquer um dos seis tipos.
  • Array — uma lista ordenada de valores, entre colchetes []. Pode conter qualquer tipo, e pode misturar tipos.
  • String — texto entre aspas duplas, com um conjunto fechado de caracteres de escape.
  • Número — inteiro, decimal ou notação científica. Sem zero à esquerda, sem NaN, sem Infinity.
  • Booleano — literalmente true ou false, em minúsculas, sem aspas.
  • null — o nada, o vazio explícito. Diferente de string vazia, diferente de zero.

Cada um, rapidinho:

{
  "objeto": {"chave": "valor"},
  "array": [1, 2, 3],
  "string": "uma string",
  "numero": 3.14159,
  "booleano": true,
  "nulo": null
}

Agora um exemplo de verdade — um registro de usuário como você acharia na resposta de uma API real:

{
  "id": 42,
  "nome": "Mariana Souza",
  "email": "mariana@exemplo.com",
  "ativo": true,
  "pontuacao": 987.5,
  "roles": ["admin", "reports"],
  "endereco": {
    "rua": "Av. Paulista, 1000",
    "cidade": "São Paulo",
    "uf": "SP"
  },
  "ultimo_acesso": "2026-08-12T14:03:00Z",
  "nota": null
}

Repare em dois detalhes. ultimo_acesso é uma string, não um tipo de data — o JSON não tem tipo de data, e a gente volta nisso adiante. E nota é null, que é diferente de uma string vazia "" e diferente de zero. Três coisas distintas que, na pressa, muita gente confunde ao tratar a resposta.

As arestas da sintaxe

A sintaxe é pequena, mas tem arestas. As pessoas tropeçam nelas o tempo todo. Vou pelas principais.

Chaves sempre com aspas duplas. {"nome": "Ana"} é válido. {nome: "Ana"} não é JSON — é JavaScript, mas não é JSON. Isso confunde todo mundo que vem do JavaScript, porque lá as chaves podem ir sem aspas. Ao copiar um objeto do console do navegador para um arquivo, você descobre isso no primeiro JSON.parse que falha.

Strings só com aspas duplas. Aspas simples não existem em JSON. 'texto' é inválido. É outra herança do JavaScript que foi cortada.

Não tem comentários. Nenhum. Nem //, nem /* */, nem #. Para um formato que nasceu dentro de uma linguagem de programação, isso parece piada. As pessoas contornam com chaves esquisitas tipo "_comentario": "não apagar este campo". (O JSON5 e o JSONC existem por causa disso; a gente fala deles mais adiante.)

Não tem vírgula final. [1, 2, 3,] é inválido. Essa é a fonte de uma boa parte dos erros que a gente vê ao copiar JSON de um lugar e colar em outro — o git diff que quebra o build por causa de uma vírgula órfã.

Números não podem ter zero à esquerda. 01 é inválido. 0.1 é válido, .5 não é, 5. não é. O expoente é permitido: 1e3, 2.5E-2. E -0 é permitido — é um número válido, e a maioria dos parsers o preserva. Detalhe que ninguém nota até precisar.

Chaves duplicadas são permitidas. O parser não é obrigado a reclamar. A especificação não define o comportamento para esse caso — a RFC 8259 diz apenas que ele é unpredictable (imprevisível); na prática, quase todo parser fica com o último valor. "Quase" — porque ninguém deveria depender disso. Se você vê um JSON com chave repetida, está vendo um problema em potencial, não uma vantagem.

Unicode entra via \uXXXX. Um \u00e7 vira ç. Para caracteres fora do plano básico — emoji, por exemplo — são necessários dois escapes, os pares substitutos (surrogate pairs): \ud83d\ude00 é o 😀. Na prática, porém, strings JSON quase sempre carregam UTF-8 cru, sem escape nenhum, e os parsers lidam bem com isso.

O conjunto completo de escapes: \" para aspas, \\ para barra invertida, \/ para barra (não é obrigatório — existe para o JSON poder ser embutido em HTML sem arriscar fechar uma tag no meio da string; hoje em dia quase ninguém usa), \b (backspace), \f (form feed), \n (nova linha), \r (retorno de carro), \t (tab) e \uXXXX. É uma lista fechada. \x41 ou \a, por exemplo, são inválidos.

Essas arestas existem por um motivo: precisão. O JSON foi desenhado para não haver ambiguidade entre um parser e outro — o mesmo documento deve ser lido da mesma forma em qualquer linguagem. O preço é que ele é mais rígido do que a linguagem que o originou.

JSON é um subconjunto do JavaScript?

Muita gente acha que JSON é a mesma coisa que um objeto literal do JavaScript. Não é. Um objeto literal do JS pode ter: aspas simples, vírgulas finais, comentários, funções, undefined, NaN, Infinity, objetos Date, chaves sem aspas. Nada disso é JSON. O JSON é um subconjunto estrito — e mesmo o "subconjunto" tem uma história meio cômica.

A primeira RFC do JSON, a 4627, de 2006, afirmava que JSON era um subconjunto do JavaScript. Ficou bonito no papel até alguém reparar em dois caracteres: U+2028 e U+2029, os separadores de linha e de parágrafo do Unicode. Eles são válidos dentro de strings em JSON — mas no JavaScript da época, no padrão ECMAScript 5, não podiam aparecer em código-fonte. Ou seja: existia JSON que era inválido como JavaScript. O formato que se dizia subconjunto da linguagem tinha um caso que a linguagem não aguentava. A RFC 8259 removeu de vez a palavra "subconjunto". Detalhe, mas um detalhe que explica por que especificações evoluem: quando a realidade desmente a sua venda, você ajusta o texto.

Por que isso importa na prática? Por causa do JSON.parse. Quando você recebe JSON de uma API e faz JSON.parse(texto), o navegador usa um parser real, não um eval disfarçado. Ele respeita as regras do JSON, valida a sintaxe e não executa código. A distinção não é acadêmica: é o que separa "ler dados" de "executar o que o servidor — ou um atacante — mandou". A seção de segurança conta essa história com mais calma.

Onde você encontra todo dia

O JSON está em todo lugar que troca dados entre processos. Uma lista rápida do que você topa numa semana normal:

Corpo de requisição e resposta de APIs REST. É o uso que todo mundo pensa primeiro. fetch para o backend, resposta em JSON, res.json(), e pronto. O servidor devolve Content-Type: application/json e o cliente não precisa de mais nada.

Arquivos de configuração. package.json, tsconfig.json, composer.json, .eslintrc, firebase.json, launch.json do VS Code. A lista é gigante. Projetos inteiros são configurados em JSON — e sofrem com a falta de comentários na mesma proporção.

localStorage e IndexedDB. O localStorage só guarda strings. O JSON é a cola que transforma seu objeto em string e de volta:

const pedido = {id: 7, itens: ["café", "croissant"]};
localStorage.setItem("pedido", JSON.stringify(pedido));
const deVolta = JSON.parse(localStorage.getItem("pedido"));

Bancos de dados. O PostgreSQL tem o tipo jsonb, que guarda JSON e permite consultar campos internos com operadores dedicados. O MongoDB não guarda JSON propriamente — guarda BSON, uma variante binária — mas o JSON é a cara que você vê no shell e nos drivers. Bancos "NoSQL" como o CouchDB guardam documentos JSON de verdade.

JSON Lines (NDJSON). Uma variação em que cada linha do arquivo é um documento JSON válido, sem vírgulas entre eles. Perfeito para logs, streams e processamento linha a linha — você lê um objeto, processa, descarta, e não precisa carregar o arquivo inteiro na memória:

{"ts":"2026-08-12T10:00:01Z","level":"info","msg":"iniciando"}
{"ts":"2026-08-12T10:00:02Z","level":"warn","msg":"cache frio"}
{"ts":"2026-08-12T10:00:03Z","level":"error","msg":"timeout no banco"}

Mensagens WebSocket. A maioria dos protocolos por cima de WebSocket fala JSON — fácil de serializar, fácil de ler num console, fácil de debugar. Um {"type":"chat.message","payload":{...}} é autoexplicativo.

Ferramentas de orquestração e CI. O Kubernetes usa YAML, mas inúmeros sistemas de CI, filas de mensagens e pipelines usam JSON para config e payload. O Terraform aceita um JSON equivalente ao HCL. O GitHub Actions permite workflows em JSON. O serverless.yml tem seu equivalente em JSON.

O padrão é o mesmo em todos os casos: um processo serializa, o outro faz o parse, e os dois falam a mesma língua sem precisar negociar nada antes. Não existe handshake, não existe schema negociado, não existe versão de formato. Esse é o trunfo do JSON — e também a fonte de vários dos seus problemas.

Como cada linguagem faz o parse

Não vou fazer tutorial de nenhuma delas — só quero que você veja o quão parecida é a história em cada linguagem. Se o formato fosse difícil de usar, esta seção teria que ser muito mais longa.

JavaScript. JSON.parse(texto) para ler, JSON.stringify(valor) para escrever. Dois métodos no objeto global JSON, prontos desde o ES5. É provavelmente a primeira API que um dev web aprende — e a última que esquece.

Python. O módulo json da biblioteca padrão: json.loads(texto) e json.dumps(dados). O loads devolve dicionários e listas; o dumps aceita a maioria dos tipos nativos. Para arquivos, json.load e json.dump. Ponto. Não precisa instalar nada.

Java. A biblioteca padrão tem algumas classes no pacote javax.json, mas na prática o mundo usa bibliotecas: Jackson ou Gson. Você anota uma classe com @JsonProperty (Jackson) ou @SerializedName (Gson) e chama um ObjectMapper ou uma instância de Gson para converter. É mais verboso, mas resolve — e é o que sustenta metade dos serviços Java por aí.

Go. encoding/json, com structs anotadas via tags:

type Usuario struct {
    ID   int    `json:"id"`
    Nome string `json:"nome"`
}

O json.Unmarshal preenche a struct; o json.Marshal faz o caminho contrário. A tipagem estática significa que campos desconhecidos somem se não estiverem na struct — e isso confunde gente vinda de linguagens dinâmicas, que espera os dados todos chegando.

Rust. serde_json, o módulo mais usado do ecossistema serde. Você deriva Serialize e Deserialize num struct, e o resto é mágica:

#[derive(Serialize, Deserialize)]
struct Usuario {
    id: i32,
    nome: String,
}

A força do serde é que a mesma trait serve para YAML, TOML e mais uma dúzia de formatos. Escreveu uma vez, serializa em tudo.

A lição aqui não é "memorize a API de cada um". É notar que todas as linguagens têm a mesma conversa: valor nativo ↔ texto JSON, em duas funções. Se o JSON fosse uma tecnologia difícil, os bindings seriam um campo de batalha e cada ecossistema teria reinventado a roda do seu jeito. Em vez disso, é a parte mais chata e mais resolvida de qualquer stack.

Segurança: lições pagas caro

O JSON tem um histórico de segurança que é basicamente uma aula de "o que acontece quando a conveniência encontra o mal-entendido".

A era do eval. No começo dos anos 2000, antes do JSON.parse existir, a forma "esperta" de ler JSON no navegador era eval("(" + texto + ")"). Aquelas aspas externas existiam porque {"chave": "valor"} no começo de uma linha parecia um bloco de código, não um objeto. O problema é que o eval não lê dados: ele executa o que você passa. Um payload malformado — ou, pior, algo que nem é JSON, só parece — vira código rodando no seu contexto de execução. O eval de dado não confiável era a porta de entrada clássica para injeção de código no navegador. O eval para parse é uma dessas ideias que morrem por um bom motivo, e deveria estar no museu junto com document.write.

JSONP. Para driblar a política de mesma origem — o CORS ainda nem existia — inventaram o JSONP: em vez de trazer dados, você trazia um script que chamava um callback com os dados dentro. O servidor devolvia algo como callback({"status":"ok"}). Funcionava, mas obrigava você a confiar num terceiro para rodar código na sua página. Hoje é relíquia, mas ainda aparece em integrações velhas — e é um dos motivos de eu torcer o nariz quando um sistema novo propõe carregar dados como script.

O buraco do array no topo. Por um bom tempo, uma resposta JSON podia começar com [. Só que arrays no topo abriam um furo de CSRF: uma página maliciosa podia sobrescrever o construtor Array, carregar a resposta do serviço alvo como <script> e capturar os dados do array — o velho JSON hijacking. A correção virou convenção de mercado: responder sempre com um objeto no topo, {"data": [...]} em vez de [...] puro. Não é a especificação que exige isso — nenhuma versão dela o faz — mas é o que toda API séria passou a fazer. Não é design: é segurança. Uma lição boa para lembrar quando alguém reclama de um envelope a mais no payload.

Poluição de protótipo. Chaves como __proto__ em JSON podem, em linguagens com herança de protótipo, contaminar todos os objetos de um processo. Uma chamada de API que devolve {"__proto__": {"isAdmin": true}} somada a um parser que mescla objetos de forma ingênua pode ser o suficiente para um ataque. O correto é parsers que tratam __proto__ como chave comum — o JSON.parse do JavaScript faz isso — e bibliotecas que não mesclam valores em protótipo.

Bombas JSON. Um documento pequeno pode esconder um gigante quando descompactado: milhares de níveis de [[[[[.... Parsers recursivos estouram a pilha; parsers que expandem tudo estouram a memória. É um DoS barato contra um servidor descuidado, e a única defesa é limitar tamanho e profundidade.

A regra moderna é uma lista curta e dura: use sempre um parser de verdade, nunca eval; limite o tamanho da resposta; limite a profundidade do aninhamento se puder; evite bibliotecas que mesclam objetos no protótipo; e trate todo JSON como dado não confiável, porque é isso que ele é.

Validação e extensões: Schema, JSON5

O JSON não traz nenhuma forma de validar dados embutida. Um objeto {"preco": "oito reais"} é tão válido quanto {"preco": 8} — o parser aceita os dois e não reclama. Para validar de verdade, o mundo criou o JSON Schema: um documento JSON que descreve o formato esperado de outro documento.

{
  "type": "object",
  "required": ["nome", "email"],
  "properties": {
    "nome": {"type": "string", "minLength": 1},
    "email": {"type": "string", "format": "email"},
    "idade": {"type": "integer", "minimum": 0}
  }
}

Com isso você valida requisições, gera documentação e até gera código. O JSON Schema é a fundação de muitas ferramentas de API — o OpenAPI usa uma versão dele. A especificação atual é a draft 2020-12, e a estrutura mudou bastante ao longo das versões; se você for mergulhar, pule direto para as drafts modernas e ignore os tutoriais de 2015.

Mas o JSON Schema não resolve a dor cotidiana de escrever JSON à mão. Aí entram as extensões pragmáticas:

  • JSON5 — "JSON for Humans". Comentários, vírgulas finais, chaves sem aspas, aspas simples, Infinity, NaN, números hexadecimais. É um JSON relaxado, sem intenção de virar padrão.
  • JSONC — "JSON with Comments". É o JSON de sempre, só que com comentários permitidos. É o que o VS Code aceita nos seus arquivos de configuração — settings.json aceita comentários, com um aviso discreto na interface.
  • HJSON — "Human JSON". Ainda mais permissivo que o JSON5, focado em legibilidade para gente.

Nenhum deles é padrão. São hacks pragmáticos — e está tudo bem, desde que você não deixe esses arquivos atravessarem a fronteira da sua aplicação. Na minha opinião, a divisão saudável é: JSON estrito para API e transporte, uma dessas variações para arquivos de config editados por humanos. Tentar usar um só formato para os dois papéis é onde as pessoas se machucam.

Seus limites e as reclamações

O JSON tem vinte e cinco anos de reclamações legítimas. Vamos às principais.

Sem comentários. O maior pecado. Arquivo de configuração em JSON não aceita comentário, então qualquer explicação vira chave falsa ou documentação separada que ninguém lê. É por isso que o TOML e o YAML existem e prosperam no nicho de configuração.

Sem tipo de data. Não existe Date em JSON. Todo mundo reinventa a roda com strings ISO 8601 ("2026-08-12T14:03:00Z"), e depois cada ecossistema cria sua própria biblioteca de parsing: date-fns, dayjs no JavaScript, java.time e Joda-Time no Java, datetime no Python. Um tipo simples teria poupado milhões de horas de conversão de fuso horário. Mas o padrão ficou como está, e o UTC é a convenção que todos acabam seguindo — cada um com seu jeitinho.

Precisão numérica. O JSON usa double IEEE-754. Números inteiros grandes demais perdem precisão: 9007199254740993 (2^53 + 1) deixa de ser ele mesmo na volta. Para bancos, IDs de 64 bits e sistemas de pagamento, isso é um problema real. As gambiarras: representar IDs como string — a mais comum — ou usar parsers que preservam o valor exato. Nenhuma das duas é elegante, e as duas aparecem em produção mais do que você imagina.

Sem binário. O JSON é texto. Imagem, áudio, arquivo: tudo vira base64, que infla o payload em cerca de 33%. Para dados pesados, é um desperdício constante de banda e de tempo de parse. As alternativas binárias existem — Protocol Buffers, MessagePack — mas você troca legibilidade por eficiência, e nem sempre vale a pena.

Aninhamento profundo. Documentos com milhares de níveis quebram parsers recursivos e tornam o dado impossível de ler. E o problema não é só o parser: é que, para o ser humano, profundidade acima de três níveis já começa a doer os olhos.

Chaves duplicadas e falta de tipo forte. O JSON não decide por você o que "1" significa — string ou número? Ele deixa em aberto, e cada sistema resolve de um jeito. Sem contrato, uma API "flexível" vira um campo minado de bugs sutis que só aparecem em produção.

Todos esses limites são reais. E, mesmo assim, o JSON sobrevive — porque os problemas que ele resolve são mais comuns do que os que ele cria.

As alternativas

Conhecer as alternativas é saber quando o JSON é a escolha errada.

YAML. Pensado para humanos: sem aspas onde não precisa, com comentários, com âncoras e aliases para reutilizar blocos. É o formato de configuração do Kubernetes e de metade das ferramentas de CI/CD. O problema: a sintaxe é notoriamente traiçoeira. Indentação significativa, o famoso caso do "Norway" — em alguns parsers, no vira booleano false — e o fato de o YAML ser um superset do JSON por especificação, mas não por implementação. Para config editada por gente, é ótimo. Para dados que viajam pela rede, é uma dor de cabeça esperando para acontecer.

TOML. Criado como resposta ao YAML e ao INI: explícito, com tipos claros ([tabelas], chave = valor), comentários permitidos, sem ambiguidades. É o formato do Cargo.toml do Rust e do pyproject.toml do Python. Ótimo para config, péssimo para dados aninhados complexos — a sintaxe de tabelas aninhadas fica ilegível rápido.

Protocol Buffers. Formato binário com schema obrigatório (arquivos .proto) e geração de código. Compacto, tipado, rápido. Mas: precisa de schema, precisa de codegen, precisa de tooling, e a depuração é um inferno comparada a ler JSON num terminal. Faz sentido quando você tem contratos estáveis e volume alto — gRPC, comunicação interna de serviços.

MessagePack e CBOR. Dois formatos binários que seguem "a cara" do JSON — os mesmos tipos, mais compactos. Para o mesmo dado, ocupam menos e parseiam mais rápido. Custo: nada é legível a olho nu. Úteis quando o tamanho importa e a legibilidade não.

BSON. A variação binária do MongoDB. Tem tipos extras — datas, bytes, ObjectId — e é o que o Mongo realmente armazena. Você raramente o toca diretamente; o driver faz a ponte entre o JSON "de fachada" e o BSON no disco.

Regra prática, na minha experiência: se o dado vai cruzar a fronteira de um sistema — API, fila, cache compartilhado — use JSON e não pense duas vezes. Se for config editada por humanos, TOML (ou JSONC, se o editor aceitar). Se o volume e a performance mandarem, e você tiver um contrato estável, Protobuf. Se for MongoDB, BSON, sem discussão.

Fechamento: formatos chatos vivem mais

O JSON está conosco há mais de vinte e cinco anos. Não porque seja bonito, nem porque seja o mais rápido, nem porque seja o mais seguro. Está porque é bom o bastante, está em todo lugar e é absurdamente simples. Três coisas que a indústria de tecnologia subestima sistematicamente.

A especificação inteira cabe numa página. Qualquer pessoa nova consegue lê-lo no primeiro dia de trabalho. Cada tentativa de "melhorar" o JSON — os schemas, os formatos binários, os supersets amigáveis — só prova o ponto: o JSON continua no meio, como língua franca, enquanto as melhorias disputam as beiradas. Ninguém conseguiu vender "JSON com comentários" como padrão universal. E isso é revelador.

A lição silenciosa é essa: em tecnologia, chato vence. Quando precisar de um formato de dados, comece pelo chato. O JSON não é a resposta certa para tudo — para números de 64 bits em sistema de pagamento, para config com comentários, para tráfego binário pesado, use outra coisa. Mas para o problema central de "dois sistemas precisam trocar dados", o JSON resolveu isso em 2001 e a solução não mudou desde então.

Se eu pudesse resumir: o JSON não é a melhor tecnologia da sua stack. É a que você menos pensa — e é exatamente por isso que ela ainda está aqui. Ele não pede aplauso, nem drama. Antes de trocá-lo por um formato "melhor", responda uma pergunta: qual problema real ele está te causando? Na maioria das vezes a resposta é "nenhum". E vinte e cinco anos de "nenhum problema" são difíceis de discutir.

O que é JSON? | ToolAct Blog | ToolAct