Um formato deliberadamente pequeno
O JSON foi projetado para ser o menor formato de dados que ainda é útil, e essa pequenez é o ponto central: é fácil escrever um parser, fácil de ler e difícil de discordar. A gramática é definida de forma idêntica pela 8259 e pela (Associação Europeia de Fabricantes de Computadores, do inglês European Computer Manufacturers Association)-404, e cabe em um cartão postal. Um documento JSON é exatamente um valor, e um valor é uma de seis coisas: um objeto, um array, uma string, um número, um booleano ou null. Todo o resto é construído a partir disso.
Os seis tipos de valor
Um objeto é um conjunto não ordenado de membros entre chaves, onde cada membro é uma chave string, dois pontos e um valor: {"name": "Ada", "active": true}. Um array é uma lista ordenada de valores entre colchetes: [1, 2, 3]. Uma string é texto entre aspas duplas, com um conjunto fixo de escapes com barra invertida para caracteres especiais. Um número é um literal decimal, que tem sutilezas que merecem o próprio artigo. Um booleano é true ou false, em minúsculas. E null é o literal null. Objetos e arrays se aninham livremente, e esse aninhamento é o que permite a uma gramática plana descrever dados arbitrariamente complexos.
As regras que as pessoas esquecem
O JSON é mais estrito do que os literais de objeto JavaScript com os quais se parece, e as diferenças são onde a validação falha. Chaves precisam ser strings entre aspas duplas: {name: 1} é inválido, e {'name': 1} também, porque aspas simples não são permitidas em lugar nenhum. Não há comentários em JSON, por mais que as pessoas os queiram. Não há vírgulas finais, então [1, 2,] é um erro. Números não podem ter um zero à esquerda ou um mais à esquerda, e não podem ser NaN nem Infinity, porque esses não são representáveis na gramática. Um documento precisa conter um único valor e nada depois dele, então dois valores em sequência, ou texto sobrando, é inválido.
Por que um validador aponta uma localização
Como a gramática é tão rígida, todo erro tem uma localização precisa: o parser sabe exatamente qual caractere violou qual regra. Um bom validador reporta não apenas que o documento é inválido mas onde, por linha e coluna, e qual caminho estrutural ele estava lendo no momento. Esse caminho, escrito como um JSON Pointer, transforma um vago "erro de sintaxe" em "o valor em /users/2/email está malformado", que é a diferença entre minutos e segundos de depuração. O formatador analisa contra essa gramática e reporta falhas exatamente assim.
Esta série, em ordem
Este artigo abre a série JSON ao pé da letra. A gramática acima é o formato inteiro; as partes abaixo são os pontos em que ele encontra parsers reais, na ordem em que um documento os encontra: suas strings, seus números, suas chaves, os dialetos tolerantes, seus bytes quando são assinados e sua tradução para .
- Escapes de string e Unicode em JSON. Os caracteres que uma string precisa escapar,
\uXXXXpara qualquer outro, e o par substituto de que um emoji precisa. - Números JSON e a armadilha da precisão. Por que um número sobrevive à gramática e não ao parser: inteiros grandes e decimais exatos perdidos para o float de 64 bits.
- Chaves duplicadas em JSON: legais, perigosas e dignas de detecção. Legal na sintaxe, indefinida no significado: como parsers discordam sobre uma chave repetida, e por que isso pode ser um problema de segurança.
- Vírgulas finais, comentários e a família JSON5. O que JSONC e JSON5 permitem e o JSON não, e como um editor tolerante produz um arquivo que uma ferramenta estrita rejeita.
- Formatação, minificação e JSON canônico. O espaço em branco não muda nada até os bytes serem assinados ou hasheados; o JSON canônico faz do mesmo dado a mesma string.
- JSON vs YAML: o que converte limpo e o que não converte. Todo documento JSON é YAML; o que converte limpo no sentido contrário e o que não tem equivalente em JSON. A ponte para a série de YAML.