Pular para o conteúdo principal

Cola de sintaxe JSON

A sintaxe do JSON, como definida pelo RFC 8259, se resume a seis caracteres estruturais, quatro caracteres de espaço em branco legais, dois contêineres, seis tipos de valor e uma gramática rigorosa para strings e números. Esta cola coloca cada regra em uma página — incluindo os erros exatos que os parsers rejeitam, de vírgulas finais a literais hexadecimais.

Só local

Cola de sintaxe JSON: explicação

A gramática completa do JSON cabe em algumas dúzias de linhas de ABNF, e praticamente todo erro de parsing do mundo real é um de uma dúzia de erros específicos. Esta página é a versão de referência desse conhecimento: cada seção enuncia uma fatia da gramática exatamente como o RFC 8259 a define, e depois mostra a regra como JSON copiável que você pode colar em um formatador ou validador e ver passar ou falhar.

Três documentos importam se você quer fontes primárias. O RFC 8259 é a norma da internet em vigor, o ECMA-404 é a norma gêmea idêntica publicada pela Ecma International, e a gramática de números dentro do RFC 8259 reutiliza deliberadamente a gramática de números da especificação ECMAScript, com as extensões octal e hexadecimal removidas. Toda regra abaixo remonta a uma dessas três fontes — nada aqui é convenção ou folclore.

As regras são curtas, mas implacáveis: não existe JSON tolerante. Um parser em conformidade aceita um documento inteiro ou o rejeita com um erro de sintaxe, e as rejeições se concentram no punhado de regras que os desenvolvedores mais esquecem — estilo de aspas, vírgulas finais, comentários, zeros à esquerda. Aprenda essas uma vez abaixo e a maioria das falhas de validação deixa de ser mistério.

As regras fixam mais rápido quando você as quebra de propósito, então mantenha o Formatador de JSON aberto em uma segunda aba e reindente cada exemplo desta página conforme lê.

Quando você quer um veredito em vez de uma formatação bonita, o Validador de JSON reporta a linha e a coluna exatas da primeira regra que um documento quebra.

Os seis caracteres estruturais

Seis caracteres de pontuação carregam toda a estrutura do JSON: as chaves { } que envolvem objetos, os colchetes [ ] que envolvem arrays, os dois-pontos : que separam uma chave de seu valor e a vírgula , que separa pares dentro de um objeto ou valores dentro de um array. Nada mais na gramática faz trabalho estrutural — todo outro caractere em um documento ou está dentro de uma string ou é um dos quatro caracteres de espaço em branco. Uma vírgula é estritamente um separador: ela pode aparecer entre dois itens, nunca antes de uma chave ou colchete de fechamento.

CaracteresNomePapel na gramática
{ }ChavesAbrem e fecham um objeto — um conjunto de pares chave/valor
[ ]ColchetesAbrem e fecham um array — uma lista ordenada de valores
:Dois-pontosSepara uma chave de seu valor dentro de um objeto
,VírgulaSepara pares ou itens de array — nunca a última coisa antes de um fechamento

Válido — vírgulas só entre itens

{"name":"Ada","tags":["math","pioneer"]}

Inválido — vírgula final antes de um fechamento

{"name":"Ada","tags":["math","pioneer"],}

Espaço em branco: exatamente quatro caracteres

Fora de strings, o JSON permite exatamente quatro caracteres de espaço em branco: o espaço (U+0020), a tabulação horizontal (U+0009), o avanço de linha (U+000A) e o retorno de carro (U+000D). Qualquer outra coisa — tabulação vertical, avanço de formulário, espaço sem quebra, uma marca de ordem de byte — é um erro de sintaxe, mesmo que muitos editores renderizem esses caracteres de forma invisível. É por isso que JSON colado de um processador de texto com tanta frequência falha na validação: o documento parece limpo na tela e contém caracteres dos quais a gramática nunca ouviu falar.

O espaço em branco também é o que torna a formatação possível. Como a gramática ignora esses quatro caracteres entre tokens, o mesmo documento pode ser uma linha longa na rede e uma árvore indentada no seu editor, e as duas formas são semanticamente idênticas — nenhum parser consegue distingui-las depois de ler.

Minificado — sem espaço em branco opcional

{"a":1,"b":[2,3]}

Formatado — espaço em branco adicionado, dados inalterados

{
  "a": 1,
  "b": [
    2,
    3
  ]
}

Strings: aspas duplas e os nove escapes

Uma string do JSON é envolvida por aspas duplas — nunca aspas simples. Dentro, a barra invertida \ introduz um escape, e o RFC 8259 define exatamente nove escapes de dois caracteres: dois são obrigatórios, \" para uma aspa dupla literal e \\ para uma barra invertida literal, porque esses dois caracteres, de outro modo, encerrariam ou corromperiam a string. Mais seis são abreviações opcionais — \/ para a barra normal e \b \f \n \r \t para os cinco caracteres de controle que aparecem com mais frequência em texto. A nona forma é \uXXXX, que escreve qualquer ponto de código Unicode pelo seu número hexadecimal de quatro dígitos.

Todo caractere fora do conjunto de escapes pode aparecer literalmente como UTF-8, e as duas formas são equivalentes: um parser entrega a string idêntica de qualquer jeito. Escapar é grafia, não dado — um ponto que o guia de escape desenvolve em profundidade.

EscapeProduzStatus segundo o RFC 8259
\"aspas duplasObrigatório — o único jeito de usar aspas dentro de uma string
\\barra invertidaObrigatório — o único jeito de escrever uma barra invertida literal
\/barra normalAbreviação opcional, legal mas raramente necessária
\b \f \n \r \tbackspace, avanço de formulário, nova linha, retorno de carro, tabulaçãoEscapes nomeados para os cinco caracteres de controle comuns
\uXXXXqualquer ponto de código, ex. \u00e9 para éForma universal — exatamente quatro dígitos hexadecimais

Forma escapada no arquivo

"quote": "she said \"hi\""
"path": "C:\\Users\\ada"
"e-acute": "\u00e9"

O que o parser devolve

quote:   she said "hi"
path:    C:\Users\ada
e-acute: é

Números: ECMAScript, menos as extensões

Um número é um inteiro ou decimal em notação simples, com um expoente opcional. O RFC 8259 adota a gramática de números do ECMAScript e remove as extensões dela: nada de hexadecimal, octal, zeros à esquerda, sinal de mais à esquerda ou ponto final solto. Um expoente usa e ou E com um sinal opcional, e o único sinal com que um número pode começar é o hífen comum. NaN, Infinity e -Infinity não são JSON — linguagens que têm essas constantes escrevem null no lugar delas, por convenção.

A precisão é deliberadamente deixada para as implementações: a gramática não diz nada sobre quantos dígitos um parser precisa honrar, então números muito longos podem chegar alterados em silêncio. Produtores interoperáveis mantêm os inteiros dentro do intervalo que a plataforma de destino representa exatamente — para os doubles IEEE 754 por trás do JavaScript, isso é até 2^53 − 1.

EscritoVereditoPor quê
42, -17, 3.14VálidoFormas inteiras e decimais simples
2.1e10, 5E-3VálidoExpoentes: e ou E, sinal opcional depois
01, -01InválidoZeros à esquerda são proibidos — escreva 1
1., .5, +6InválidoUm ponto precisa de dígitos dos dois lados; nada de mais à esquerda
0x1F, 1_000InválidoHexadecimal e separadores de dígitos são extensões do JavaScript
NaN, InfinityInválidoNão fazem parte da gramática; o JSON não tem essas constantes
9007199254740993ArriscadoFaz o parsing, mas excede o intervalo de inteiros exatos dos doubles IEEE 754

Os três literais e as cinco rejeições clássicas

Três tokens puros completam o conjunto de valores: true, false e null. São minúsculos e sem aspas — True, FALSE e None são erros de sintaxe, não capitalização criativa. Ao redor deles, a gramática traça cinco linhas que explicam quase todo documento rejeitado lá fora:

  • Sem comentários. O RFC 8259 não tem sintaxe de comentário; // ou /* */ em qualquer lugar é um erro de sintaxe. Anote com uma chave irmã como "_comment" quando o formato estiver sob seu controle.
  • Sem vírgulas finais. [1, 2, 3,] e {"a":1,} são inválidos, por mais simpáticos que pareçam — a vírgula é um separador, e não pode separar um item de nada.
  • Sem aspas simples e sem chaves sem aspas. {name:'ada'} é JSON inválido; {"name":"ada"} é a única grafia da gramática.
  • Sem chaves duplicadas — oficialmente. A gramática permite que um nome apareça duas vezes, mas o RFC 8259 §4 deixa para as implementações decidir qual valor vence, então um documento que dependa de duplicatas não tem significado definido.
  • Qualquer valor de nível superior. Desde o RFC 8259, um documento inteiro pode ser uma string, número, booleano ou null puro — a regra de só objetos e arrays do RFC 4627 caiu fora, e "hello" ou 42 são documentos JSON completos.

Codificação: UTF-8 e as regras no nível de bytes

O RFC 8259 §8.1 fixa a codificação de bytes: texto JSON trocado entre sistemas que não fazem parte de um ecossistema fechado precisa estar codificado em UTF-8. Não existe JSON em UTF-16 ou UTF-32 na rede aberta, e produtores não devem antepor uma marca de ordem de byte — um parser pode ignorar um BOM à esquerda em vez de errar, mas nada em conformidade emite um. Repare como as camadas se separam: escapar com \uXXXX é uma escolha de notação dentro de strings individuais, enquanto UTF-8 é uma propriedade do documento inteiro, e as duas resolvem problemas diferentes.

Isso fecha a gramática. O jeito mais rápido de fixar essas regras é rodar seus próprios documentos contra elas — formate um payload real, quebre uma regra por vez e leia cada erro do validador. Dez minutos de falha de propósito ensinam mais do que mais uma passada por esta página.

Perguntas frequentes

Posso colar dados reais de API nas ferramentas linkadas desta página?

Sim. O formatador e o validador deste site rodam inteiramente no seu navegador: seu documento é interpretado por JavaScript dentro da aba, e não há etapa de envio para auditar. Você mesmo pode confirmar — o painel Network do navegador fica em silêncio enquanto as ferramentas trabalham, e a Content-Security-Policy do site bloqueia conexões de saída, então nem uma cópia modificada da página conseguiria transmitir seus dados.

O JSON permite aspas simples para strings?

Não. O RFC 8259 define strings com aspas duplas, tanto para chaves quanto para valores, e não dá significado algum às aspas simples — um parser que encontra 'hello' falha imediatamente, enquanto "hello" é a única grafia válida. Ferramentas que leem aspas simples de bom grado estão interpretando JSON5 ou outro superconjunto, não JSON, e é por isso que a saída delas ainda pode ser rejeitada por consumidores mais rigorosos.

O que exatamente é uma vírgula final e por que é um erro?

Posição, não caractere. Uma vírgula entre dois itens é um separador; uma vírgula imediatamente antes de } ou ] separaria um item de nada, e a gramática proíbe isso. É a razão mais comum, isolada, de um arquivo editado à mão falhar na validação — e é por isso que geradores, minificadores e ferramentas de formatação removem as vírgulas finais por você antes de escrever.

Por que números do JSON não podem ter zeros à esquerda, como 007?

Zeros à esquerda eram como literais octais (base 8) eram escritos em JavaScript antigo, e o RFC 8259 tira a gramática de números do ECMAScript com as extensões octal e hexadecimal removidas — então 007 é rejeitado para que uma grafia signifique um valor. Escreva 7, e armazene identificadores como códigos postais como strings sempre que um zero à esquerda fizer parte do valor.

Chaves duplicadas em um objeto JSON são legais?

A gramática permite que um nome apareça duas vezes, mas a norma deliberadamente se recusa a definir o resultado: o RFC 8259 observa que as implementações reportam o último valor, o primeiro valor ou um erro. Um documento cujo significado depende de duplicatas, portanto, não é JSON interoperável — trate duplicatas como um bug mesmo quando o seu parser em particular aceita silenciosamente.

Quão grande pode ser um número JSON antes de a precisão quebrar?

A gramática não estabelece limite de dígitos, mas a maioria dos parsers decodifica para floats de dupla precisão IEEE 754, que representam inteiros exatamente só até 2^53 − 1. Um identificador de 17 dígitos como 9007199254740993 pode chegar alterado em silêncio — o motivo clássico de os SDKs de APIs com ids de 64 bits instruírem você a tratá-los como strings em vez de números.

Onde posso ler os padrões citados aqui?

  • RFC 8259 — O formato de intercâmbio de dados JavaScript Object Notation (JSON)
  • ECMA-404 — A sintaxe de intercâmbio de dados JSON
  • RFC 4627 — O tipo de mídia application/json para JavaScript Object Notation (JSON) (obsoleta; o padrão JSON atual é a RFC 8259)