JSON1

Formatos

JSON vs YAML

Os dois formatos descrevem as mesmas estruturas: objetos, arrays, strings, números, booleanos, null. As diferenças que importam na prática são quem escreve o arquivo, se comentários são permitidos, e com que agressividade o parser adivinha o que você quis dizer com um texto sem aspas.

Qual usar

A divisão útil não é técnica, é sobre o autor. JSON é o que os programas escrevem e leem: é gerado, transmitido e parseado sem ninguém no meio. YAML é o que as pessoas escrevem à mão e voltam a ler seis meses depois.

Essa única pergunta resolve a maioria dos casos. Uma API HTTP retorna JSON — YAML não traria nada, e todo cliente já tem um parser. Um pipeline de CI, um manifesto do Kubernetes ou a configuração de um app são YAML, porque uma pessoa os mantém e precisa deixar uma nota explicando por que o timeout é de 45 segundos.

  • Formato de transporte entre máquinas — JSON. Menor, parseável em qualquer lugar, sem ambiguidade a resolver.
  • Configuração que uma pessoa edita — YAML. Comentários e menos pontuação são toda a razão de existir dele.
  • Dados que você armazena e consulta — JSON. Bancos de dados indexam; quase nenhum indexa YAML.
  • Qualquer entrada não confiável — JSON. A gramática é mínima, então há muito menos que possa dar errado.

O que realmente muda

YAML 1.2 é um superconjunto de JSON: qualquer documento JSON válido também é YAML válido. O contrário não vale, e é nessas lacunas que a conversão perde coisas.

Comportamentos que mudam ao mover um documento entre os dois formatos.
JSONYAML
ComentáriosNão são permitidos# até o fim da linha
EstruturaChaves e colchetesIndentação, ou chaves
Aspas em stringsSempre obrigatóriasOpcionais, e aí está a pegadinha
Vírgulas finaisRejeitadasNão se aplica
Chaves duplicadasA última vence, silenciosamenteErro em parsers estritos
Strings multilinhaApenas escapes \nBlocos | e >
Âncoras e reusoNão existem&anchor e *ref

Converter JSON para YAML

Uma estrutura aninhada converte sem problemas, e o resultado é de fato mais curto: a pontuação que o JSON precisa passa a ser carregada pela indentação. Arrays ficam no nível de indentação do pai, que é o estilo usual e o que a maioria dos linters espera.

Repare no que aconteceu com env: um array de objetos vira uma lista de traços, com a primeira chave de cada objeto na mesma linha do traço e o resto indentado abaixo. É a forma que Kubernetes e GitHub Actions usam.

JSON de entrada

{
  "service": "api",
  "replicas": 3,
  "ports": [8080, 8443],
  "env": [
    { "name": "LOG_LEVEL", "value": "debug" },
    { "name": "REGION", "value": "eu" }
  ],
  "limits": { "cpu": "500m", "memory": "512Mi" }
}

YAML de saída

service: api
replicas: 3
ports:
- 8080
- 8443
env:
- name: LOG_LEVEL
  value: debug
- name: REGION
  value: eu
limits:
  cpu: 500m
  memory: 512Mi
Saída real do conversor /json-to-yaml/. Objetos e arrays vazios continuam visíveis como {} e [] em vez de virarem linhas em branco que você não consegue ver.

A armadilha das aspas

Essa é a que custa tempo de verdade, e só morde no sentido do YAML. Em JSON, "01234" é inequivocamente uma string, porque strings sempre levam aspas. Em YAML as aspas são opcionais — então o parser tem que adivinhar, e ele adivinha a partir dos caracteres.

Converter a partir de JSON é seguro, porque a ferramenta sabe com o que começou. Tudo que seria relido como número ou booleano sai entre aspas:

JSON de entrada

{
  "zip": "01234",
  "version": "1.10",
  "enabled": "yes"
}

YAML de saída

zip: "01234"
version: "1.10"
enabled: "yes"
As aspas não são enfeite. Tire-as e o próximo parser lê outros valores.

Por que YAML escrito à mão perde dados

Agora os mesmos três campos digitados à mão, sem aspas. É essa a falha que as pessoas encontram, e nada avisa:

  • Zeros à esquerda — CEPs, telefones e identificadores de conta perdem todos. 01234 vira 1234.
  • Zeros à direita1.10 vira 1.1, então uma versão deixa de casar.
  • `yes` e `no` — nosso parser mantém como strings, igual ao YAML 1.2. Parsers 1.1 mais antigos, incluindo o PyYAML por padrão, transformam no em false. É o problema da Noruega: o código de país NO vira booleano.

YAML escrito à mão

zip: 01234
version: 1.10
enabled: yes

Parseado como JSON

{
  "zip": 1234,
  "version": 1.1,
  "enabled": "yes"
}
O zero à esquerda sumiu, 1.10 virou 1.1, e um CEP agora é aritmética. Os três são saída real de /yaml-to-json/.

O que sobrevive à ida e volta

De JSON para YAML e de volta não se perde nada, porque as aspas são escritas por você pela ferramenta. De YAML escrito à mão para JSON e de volta, sim — e a perda acontece na entrada, antes de qualquer conversão.

Então o hábito seguro é uma regra só: coloque aspas em toda string no YAML que possa ser lida como outra coisa. Números guardados como texto são a categoria inteira — identificadores, versões, CEPs, códigos de país e qualquer coisa com zero à esquerda.

  • Comentários não sobrevivem em nenhuma direção. JSON não tem onde colocá-los, então a conversão descarta cada linha #.
  • Âncoras e aliases são expandidos, não preservados: reuso vira repetição.
  • A ordem das chaves é mantida, o que importa mais para revisar um diff do que para a correção.