JSON1

Formatos

JSON vs YAML

Los dos formatos describen las mismas estructuras: objetos, arrays, cadenas, números, booleanos, null. Las diferencias que importan en la práctica son quién escribe el archivo, si se permiten comentarios, y con cuánta agresividad el parser adivina qué querías decir con un texto sin comillas.

Cuál usar

La división útil no es técnica, es sobre el autor. JSON es lo que los programas escriben y leen: se genera, se transmite y se parsea sin que intervenga una persona. YAML es lo que la gente escribe a mano y vuelve a leer seis meses después.

Esa única pregunta resuelve la mayoría de los casos. Una API HTTP devuelve JSON: YAML no aportaría nada y todos los clientes ya tienen un parser. Un pipeline de CI, un manifiesto de Kubernetes o la configuración de una app son YAML, porque los mantiene una persona que necesita dejar una nota explicando por qué el timeout es de 45 segundos.

  • Formato de transporte entre máquinas — JSON. Más pequeño, parseable en todas partes, sin ambigüedad que resolver.
  • Configuración que edita una persona — YAML. Los comentarios y la menor puntuación son toda su razón de ser.
  • Datos que almacenas y consultas — JSON. Las bases de datos lo indexan; casi ninguna indexa YAML.
  • Cualquier entrada no confiable — JSON. Su gramática es mínima, así que hay mucho menos que pueda salir mal.

Qué cambia de verdad

YAML 1.2 es un superconjunto de JSON: cualquier documento JSON válido también es YAML válido. Al revés no ocurre, y en esos huecos es donde la conversión pierde cosas.

Comportamientos que cambian al mover un documento entre ambos formatos.
JSONYAML
ComentariosNo se permiten# hasta fin de línea
EstructuraLlaves y corchetesIndentación, o llaves
Comillas en cadenasSiempre obligatoriasOpcionales, ahí está la trampa
Comas finalesSe rechazanNo aplica
Claves duplicadasGana la última, en silencioError en parsers estrictos
Cadenas multilíneaSolo escapes \nBloques | y >
Anclas y reutilizaciónNo existen&anchor y *ref

Convertir JSON a YAML

Una estructura anidada se convierte sin problemas, y el resultado es realmente más corto: la puntuación que JSON necesita la asume la indentación. Los arrays quedan al nivel de indentación de su padre, que es el estilo habitual y lo que esperan la mayoría de los linters.

Fíjate en qué pasó con env: un array de objetos se vuelve una lista de guiones, con la primera clave de cada objeto en la misma línea del guion y el resto indentado debajo. Es la forma que usan tanto Kubernetes como GitHub Actions.

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 salida

service: api
replicas: 3
ports:
- 8080
- 8443
env:
- name: LOG_LEVEL
  value: debug
- name: REGION
  value: eu
limits:
  cpu: 500m
  memory: 512Mi
Salida real del conversor /json-to-yaml/. Los objetos y arrays vacíos siguen visibles como {} y [] en lugar de volverse líneas en blanco que no puedes ver.

La trampa de las comillas

Esta es la que cuesta tiempo real, y solo muerde en la dirección de YAML. En JSON, "01234" es inequívocamente una cadena, porque las cadenas siempre llevan comillas. En YAML las comillas son opcionales, así que el parser tiene que adivinar, y adivina a partir de los caracteres.

Convertir desde JSON es seguro, porque la herramienta sabe con qué empezó. Todo lo que se releería como número o booleano sale entre comillas:

JSON de entrada

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

YAML de salida

zip: "01234"
version: "1.10"
enabled: "yes"
Las comillas no son decoración. Quítalas y el siguiente parser leerá otros valores.

Por qué el YAML escrito a mano pierde datos

Ahora los mismos tres campos escritos a mano, sin comillas. Este es el fallo con el que se topa la gente, y nada lo avisa:

  • Ceros iniciales — códigos postales, teléfonos e identificadores de cuenta los pierden todos. 01234 pasa a ser 1234.
  • Ceros finales1.10 pasa a 1.1, así que una versión deja de coincidir.
  • `yes` y `no` — nuestro parser los mantiene como cadenas, igual que YAML 1.2. Los parsers 1.1 más antiguos, incluido PyYAML por defecto, convierten no en false. Es el problema de Noruega: el código de país NO se vuelve booleano.

YAML escrito a mano

zip: 01234
version: 1.10
enabled: yes

Parseado como JSON

{
  "zip": 1234,
  "version": 1.1,
  "enabled": "yes"
}
El cero inicial desapareció, 1.10 se volvió 1.1, y un código postal ahora es aritmética. Los tres son salida real de /yaml-to-json/.

Qué sobrevive a la ida y vuelta

De JSON a YAML y de vuelta no se pierde nada, porque las comillas las escribe la herramienta por ti. De YAML escrito a mano a JSON y de vuelta sí, y la pérdida ocurre en la entrada, antes de cualquier conversión.

Así que el hábito seguro es una sola regla: pon comillas a toda cadena en YAML que pueda leerse como otra cosa. Los números guardados como texto son la categoría completa: identificadores, versiones, códigos postales, códigos de país y cualquier cosa con un cero inicial.

  • Los comentarios no sobreviven en ninguna dirección. JSON no tiene dónde ponerlos, así que la conversión descarta cada línea #.
  • Las anclas y los alias se expanden, no se preservan: la reutilización se vuelve repetición.
  • El orden de las claves se mantiene, lo que importa más para revisar un diff que para la corrección.