Também disponível em: English · Español · Français · العربية
JSON Pointer: avaliador de ponteiros da RFC 6901
Aponte para exatamente um valor dentro de um documento JSON e veja como cada token foi resolvido — ou exatamente por que não foi.
O que é um JSON Pointer
Um JSON Pointer é uma string curta que nomeia exatamente um lugar dentro de um documento JSON. É uma sequência de tokens, cada um introduzido por uma barra, de modo que /paths/~1users/get desce da raiz para o membro chamado paths, depois para o chamado /users e depois para get. A RFC 6901 o define em oito páginas, e é o que JSON Patch, as referências de JSON Schema e o OpenAPI usam para dizer a que se referem.
A palavra decisiva é exatamente. Um ponteiro nomeia um lugar, e ou ele está lá ou não está — o que o separa do JSONPath, onde uma única consulta pode devolver cem nós ou nenhum e onde implementações diferentes devolvem conjuntos diferentes. Num ponteiro não há nada sobre o que discordar, e foi por isso que os formatos que precisam ser inequívocos o escolheram.
Essa gramática mínima tem mais arestas do que parece, e esta ferramenta mostra todas. Cole um documento, escreva um ponteiro, e ele avalia token a token: em que cada um foi procurado, o que encontrou e, quando não encontrou nada, qual regra o barrou.
Como usar
- Cole um documento. Começa com o documento de exemplo da norma, então qualquer resposta pode ser conferida na própria RFC 6901. O que não for JSON válido é avisado em vez de adivinhado.
- Escreva um ponteiro. A string vazia nomeia o documento inteiro; o resto começa por barra. Dentro de um token, o til se escreve ~0 e a barra ~1. Ou escolha um da lista com todos os ponteiros do seu documento, lá embaixo.
- Leia o rastro. Cada linha mostra um token, se ele foi procurado num objeto ou num array, e o que voltou. Uma falha nomeia a regra específica em vez de simplesmente não devolver nada.
A regra de escape e a ordem em que ela precisa acontecer
Dois caracteres não podem aparecer literalmente dentro de um token. A barra abriria um token novo e o til é o caractere de escape, então escrevem-se ~1 e ~0. Esse é todo o esquema de escape, e é menor do que a maioria espera: não há barra invertida, nem codificação por porcentagem, nem nenhum outro escape. Um til seguido de qualquer coisa que não seja 0 ou 1 não é um ponteiro válido.
O interessante é a ordem. A decodificação precisa transformar ~1 em barra primeiro e ~0 em til depois. Ao contrário, ~01 vira ~1 e então uma barra, quando a resposta certa são os dois caracteres ~1. A norma dedica um parágrafo inteiro a isso e nomeia o resultado errado explicitamente — o que costuma ser sinal de que implementações reais erram. Esta ferramenta decodifica numa passada só, então o perigo não é evitado lembrando de uma ordem: ele simplesmente não pode surgir.
Na codificação vale o inverso, com a mesma armadilha: é preciso escapar o til antes e a barra depois, ou um nome que contenha uma barra produz um token que decodifica para outra coisa. A ferramenta escapa conforme percorre, pelo mesmo motivo.
Quatro regras que surpreendem
Um índice de array não pode ter zero à esquerda. A gramática aceita um zero sozinho, ou um dígito de um a nove seguido de quaisquer dígitos, e nada mais — então /foo/01 é erro de sintaxe e não o índice um. É exatamente aqui que uma implementação em JavaScript escorrega, porque as duas maneiras óbvias de ler um número aceitam: uma transforma o texto 01 no número um, e a outra tira um número do começo de 1abc e joga o resto fora. Nenhuma é o que a gramática diz.
Uma barra sozinha não é um ponteiro vazio. É um token cujo nome é a string vazia, então aponta para o membro chamado nada — um nome de membro perfeitamente legal em JSON, e que o documento de exemplo da norma inclui justamente por isso. O ponteiro vazio, sem nenhum caractere, é o que nomeia o documento inteiro.
O caractere - sozinho nomeia a posição depois do último elemento de um array. Não é um índice e nunca há valor ali; existe para o JSON Patch poder dizer acrescente aqui. Reportar como erro seria errado e devolver um valor seria mentira, então a ferramenta lhe dá uma resposta própria.
Nomes de membro são comparados por ponto de código, e a norma diz sem rodeios que nenhuma normalização Unicode é feita. Duas grafias da mesma letra acentuada — uma composta num caractere só, outra escrita como letra mais marca combinante — parecem idênticas na tela e são membros diferentes. Se um ponteiro que parece certo se recusa a resolver, vale checar isso antes de qualquer coisa.
A forma de fragmento, e o que ela não significa
Um ponteiro também pode ser escrito num fragmento de URI, e a norma repete os mesmos doze exemplos nessa forma: o ponteiro é codificado em UTF-8 e tudo o que um fragmento não carrega vira codificação por porcentagem, então o sinal de porcentagem vira %25 e o espaço vira %20. A ferramenta mostra essa grafia para o que você digitar e deixa copiar.
E aí vem a frase que quase ninguém previria, na mesma seção que imprime esses exemplos: a sintaxe de identificador de fragmento de application/json não é o JSON Pointer. Um tipo de mídia precisa declarar o JSON Pointer como sua sintaxe de fragmento, e o JSON puro nunca declarou. Então uma URL terminada em ponteiro significa algo dentro de um JSON Schema ou de uma referência OpenAPI, onde o formato diz que sim, e é decorativa num .json comum, onde nada lhe dá esse sentido.
Vale dizer também até onde a ferramenta vai. Ela avalia ponteiros e não aplica patches; a RFC 6902 se apoia nesta gramática para adicionar, remover e mover valores, e isso é outro trabalho. Trabalha sobre o documento que você cola, sem seguir referências para outros arquivos. E é estrita de propósito: onde uma biblioteca poderia aceitar calada um zero à esquerda ou um til solto, aqui se diz qual regra foi quebrada — porque um ponteiro que funciona numa implementação e falha em outra é justamente o problema que ele existe para evitar.
Por que é grátis?
Percorrer um documento token a token são algumas centenas de linhas de manipulação de strings, e o seu navegador faz isso enquanto você digita. Nenhum servidor vê o seu JSON, então não há nada a medir nem conta a criar.
Nada é enviado. O que você colar fica nesta aba.