O Que É JSON? Guia Completo com Exemplos e Erros Comuns
JSON (JavaScript Object Notation) é um formato de texto para representar dados estruturados como pares de chave e valor e listas ordenadas, construído a partir de apenas seis tipos de valor. É o formato que praticamente toda API na web usa para enviar e receber dados, e também aparece o tempo todo em arquivos de configuração, logs e bancos NoSQL. Apesar de lembrar um objeto do JavaScript, o JSON segue um conjunto pequeno e rígido de regras, e quebrar qualquer uma delas torna o documento inteiro impossível de ler.
O que é o JSON de fato
Todo documento JSON é montado a partir de exatamente seis tipos de valor:
- String, sempre entre aspas duplas, como
"ola" - Number (número), como
42ou3.14 - Boolean (booleano),
trueoufalse null- Object (objeto), um conjunto de pares chave-valor entre
{} - Array (lista), uma sequência ordenada de valores entre
[]
E é só isso. Não existe tipo data, não existe undefined, não existe tipo função, nada além desses seis. Objetos e arrays podem se aninhar uns dentro dos outros o quanto for preciso, mas todo valor, em qualquer nível, precisa ser um desses seis tipos.
As regras de sintaxe que acompanham esses tipos são igualmente fixas:
- As chaves de um objeto precisam ser strings entre aspas duplas.
`{"nome":"Ada"}`é válido;`{nome:"Ada"}`não é. - Sem vírgula sobrando no final. A última propriedade de um objeto e o último item de um array não podem ter vírgula depois deles.
- Nenhum tipo de comentário é permitido, nem
//nem/* */. - Strings e chaves usam só aspas duplas. Aspas simples não são sintaxe JSON válida, mesmo sendo válidas em JavaScript.
- Uma chave nunca pode ficar sem aspas, por mais simples que seja o nome.
NaN,Infinityeundefinednão são valores JSON válidos, mesmo sendo válidos em JavaScript.- Funções não podem ser representadas em JSON. Não existe forma de serializar comportamento, só dado.
Quebre qualquer uma dessas regras e o parser para na hora e reporta um erro, em vez de tentar adivinhar o que você quis dizer.
JSON vs. um objeto literal do JavaScript
A sintaxe de {} e [] do JSON foi emprestada dos objetos e arrays literais do JavaScript, e é justamente por isso que os dois se confundem tanto. Na tela, parecem quase idênticos, mas um objeto literal do JavaScript é mais permissivo em cada ponto onde o JSON é rígido:
| Característica | JSON | Objeto literal do JavaScript |
|---|---|---|
| Chaves precisam de aspas | Sim, só aspas duplas | Não, aspas são opcionais |
| Vírgula sobrando é permitida | Não | Sim |
| Comentários são permitidos | Não | Sim |
| Strings com aspas simples | Não | Sim |
| Funções como valor | Não | Sim |
undefined como valor | Não | Sim |
É aqui que boa parte do tempo de debug se perde. Copiar um objeto literal direto de um arquivo JavaScript (chaves sem aspas, vírgula sobrando e tudo mais) e colar num lugar que espera JSON gera algo que roda perfeitamente como JavaScript, mas quebra no instante em que JSON.parse toca nele. O JSON não é um subconjunto do JavaScript que dá para escrever no improviso; é um formato separado e mais rígido que só por acaso compartilha a pontuação com outro.
Exemplo prático: minificando e formatando uma resposta de API real
Pegue um objeto de usuário típico que uma API poderia devolver:
{
"id": 1,
"name": "Ada Lovelace",
"email": "[email protected]",
"roles": [
"admin",
"user"
],
"active": true,
"meta": null
}
Essa versão formatada, com indentação de 2 espaços, tem 145 caracteres. O mesmo dado minificado, sem nenhum espaço ou quebra de linha, fica assim:
{"id":1,"name":"Ada Lovelace","email":"[email protected]","roles":["admin","user"],"active":true,"meta":null}
São 107 caracteres, cerca de 35% menor, e a diferença é puramente espaço em branco. Nenhuma chave ou valor mudou; o dado é exatamente o mesmo.
É por isso que APIs enviam JSON minificado na rede: em escala, cortar esses 35% de bytes em milhões de requisições representa economia real de banda e latência, e nenhum código do lado do cliente precisa da indentação para interpretar o valor corretamente. Só que essa mesma string minificada é quase ilegível para uma pessoa. Quando você está debugando uma resposta e precisa enxergar o aninhamento, os nomes das chaves e onde um array começa e termina, você formata de volta para a versão indentada. O mesmo dado, dois trabalhos diferentes: um para a máquina, outro para você.
Formate o seu próprio JSON
Cole abaixo um JSON minificado ou bagunçado para ver ele reformatado com indentação correta, ou use ao contrário para minificar um documento formatado antes de mandar para algum lugar onde tamanho importa.
Erros comuns e casos extremos
Vírgula sobrando no final. Dado `{"id":1,"name":"Ada",}`, o V8 (o motor por trás do Chrome e do Node.js) reporta:
Expected double-quoted property name in JSON at position 21 (line 1 column 22)
A vírgula depois de "Ada" não tem nada depois dela, e o JSON não tem noção de separador final opcional. O SpiderMonkey do Firefox formula os erros de um jeito diferente, mas o parse falha do mesmo jeito em qualquer motor compatível com JSON.
Chave sem aspas. `{id:1}` falha com:
Expected property name or '}' in JSON at position 1 (line 1 column 2)
O parser espera uma string entre aspas duplas logo depois do { e encontra um identificador solto no lugar.
Chave com aspas simples. `{'a':1}` cai na mesma classe de erro:
Expected property name or '}' in JSON at position 1 (line 1 column 2)
Aspas simples não são uma forma válida de abrir uma string em JSON, então o parser trata 'a' exatamente como trataria uma chave sem aspas: não é um nome de propriedade válido.
NaN e undefined como valores. `{"a":NaN}` produz:
Unexpected token 'N', "{"a":NaN}" is not valid JSON
E `{"a":undefined}` produz:
Unexpected token 'u', "{"a":undefined}" is not valid JSON
Os dois são válidos em um objeto literal do JavaScript, mas não têm representação em JSON. Se um valor pode virar NaN ou undefined na sua aplicação, converta para null ou para uma string antes de serializar.
Chaves duplicadas sobrescrevem em silêncio. `{"a":1,"a":2}` é sintaticamente válido, sem erro nenhum, e vira `{"a":2}` ao ser interpretado. A maioria dos parsers, incluindo o do JavaScript, mantém só a última ocorrência de uma chave repetida e descarta a anterior sem avisar nada. Essa é uma fonte sutil de bugs reais: uma ferramenta de build que concatena fragmentos de configuração, ou um arquivo editado à mão onde alguém colou o mesmo bloco duas vezes, pode acabar com a mesma chave aparecendo duas vezes, e como não há erro, ninguém percebe até o valor errado aparecer em algum lugar mais adiante.
Perguntas frequentes
O que é JSON?
JSON (JavaScript Object Notation) é um formato de texto para dados estruturados, construído a partir de seis tipos de valor: strings, números, booleanos, null, objetos e arrays. É o formato mais comum em requisições e respostas de API, e também aparece em arquivos de configuração e em muitos bancos de dados.
JSON é a mesma coisa que um objeto do JavaScript?
Não. O JSON parece um objeto literal do JavaScript, mas é mais rígido: chaves precisam de aspas duplas, vírgula sobrando não é permitida, comentários não são permitidos, e valores como undefined ou uma função não podem ser representados de jeito nenhum. Um objeto literal do JavaScript permite tudo isso; o JSON não permite nada disso.
Por que uma vírgula sobrando quebra meu JSON?
Porque a gramática do JSON não tem regra nenhuma para uma vírgula extra depois do último item de um objeto ou array. Um parser lendo `{"id":1,"name":"Ada",}` espera outro nome de propriedade depois da vírgula e encontra a chave de fechamento no lugar, que é exatamente o que o erro “Expected double-quoted property name in JSON” está reportando.
O JSON aceita comentários?
Não. Não existe sintaxe para comentários // ou /* */ em nenhum lugar da especificação JSON. Se você precisa anotar um arquivo JSON para outras pessoas lerem, as saídas costumeiras são um arquivo de documentação separado, uma chave irmã tipo "_comment" tratada como dado comum, ou trocar o formato do arquivo para um que aceite comentários, como JSON5 ou YAML.
Qual a diferença entre formatar e minificar JSON? Formatar (também chamado de embelezar ou prettificar) adiciona indentação e quebras de linha para uma pessoa conseguir ler a estrutura de relance. Minificar remove todo esse espaço em branco para produzir a menor string possível. As duas versões representam exatamente o mesmo dado; a diferença é puramente de apresentação, e é comum converter entre as duas dependendo se o JSON vai ser lido por uma pessoa ou enviado pela rede.
Meus dados são enviados a um servidor quando uso um formatador online?
Com o Formatador de JSON do pluri.tools, não. Formatar, minificar e validar rodam com JSON.parse e JSON.stringify puros, dentro do motor JavaScript do seu navegador. Não existe fetch nem chamada de rede envolvida, então o JSON que você cola nunca sai do seu dispositivo.