abox.tools

Idioma: Español

Cómo formatear JSON sin entregárselo a nadie

Formatear JSON debería cambiar los espacios y nada más. La mayoría de las herramientas que se ofrecen a hacerlo cambian más que eso, y ninguna lo menciona. Esto es en qué fijarse, cómo leer el error cuando el archivo no se deja analizar, y por qué merece la pena pensarse la casilla en la que pegas un archivo de configuración.

Abrir Formateador de JSON JSON, XML, HTML, CSS y YAML, formateados o convertidos. Nada se pega en el servidor de nadie.

Ver como Markdown

La respuesta corta

Abre Texto y código, pega el JSON en la casilla, y léelo. La disposición ocurre mientras escribes, el lenguaje se deduce del texto, y la sangría son dos espacios salvo que digas otra cosa. No se sube nada, porque no hay adónde: el analizador son unos cientos de líneas de JavaScript ejecutándose en la pestaña que ya tienes abierta.

Todo lo de abajo es lo que merece la pena saber antes de pegar un archivo de configuración en cualquiera de las alternativas: qué puede cambiar un formateador, qué cambian casi todos de todas formas, y cómo leer el error cuando el archivo no se deja analizar siquiera.

Dos paneles: una sola línea de JSON a la izquierda y el mismo documento formateado con dos espacios de sangría a la derecha.
Una línea entra, algo legible sale. Para eso no se envió nada a ningún sitio.

Qué es formatear y qué no

JSON casi no tiene sintaxis. Un objeto, un array, una cadena, un número, y las tres palabras true, false y null. Entre esas piezas, los espacios no significan nada: el archivo

{"name":"thing","tags":["local","offline"]}

y el archivo

{
  "name": "thing",
  "tags": [
    "local",
    "offline"
  ]
}

son el mismo documento. Formatear es el trabajo de pasar del primero al segundo, y ese es todo el trabajo. Cualquier otra cosa que un formateador le haga a tu archivo — reordenar, redondear, tirar cosas — es un cambio en lo que el documento dice, hecho sin que nadie lo pidiera.

Tres de esos cambios son bastante comunes como para nombrarlos, porque son silenciosos y porque son lo que hace por defecto un formateador escrito en una tarde.

Las tres cosas que un formateador no debe cambiar

El orden de tus claves

Esta es la que pilla a la gente. La forma obvia de escribir un formateador de JSON en JavaScript es llamar a JSON.parse y luego a JSON.stringify con una sangría, y esa pareja no conserva el orden de las claves que parecen enteros:

Object.keys(JSON.parse('{"10":"a","2":"b","x":"c"}'))
// ['2', '10', 'x']

No es un fallo del código de nadie. Los objetos de JavaScript están especificados para poner primero las claves parecidas a enteros, en orden numérico ascendente, y todo valor que pasa por JSON.parse se convierte en un objeto de JavaScript. Un formateador construido así reordenará un archivo indexado por id, por número de puerto, por año o por código de estado HTTP, y lo hará sin decir palabra.

Que importe o no depende del archivo. Los objetos JSON no tienen orden en principio, así que técnicamente no se rompe nada — pero el diff contra la versión de tu repositorio será enorme, la revisión será ilegible, y si algo más abajo lee el archivo en orden, el comportamiento cambia.

Los dígitos de tus números

JSON no dice cuán grande puede ser un número, y JavaScript sí: todo número es un doble. Así que un formateador que analiza a doble y lo vuelve a imprimir pierde todo lo que un doble no puede contener.

JSON.stringify(JSON.parse('{"id":123456789012345678901}'))
// {"id":123456789012345680000}

JSON.stringify(JSON.parse('{"size":1e999}'))
// {"size":null}

Un id de veintiún dígitos — un id de Twitter, un id Snowflake, una referencia bancaria — vuelve como un número distinto, y un valor demasiado grande para un doble vuelve como null. Los dos archivos siguen analizándose, y ninguno de los dos es el archivo con el que empezaste.

La salida es no analizar los números en absoluto. A un formateador solo le hace falta saber dónde empieza y dónde acaba un número para colocar el documento; nunca necesita su valor, así que lo seguro es copiar los dígitos exactamente como estaban escritos. Eso es lo que hace la herramienta de aquí.

Tus claves repetidas

{"a": 1, "a": 2} es JSON válido, y el estándar se niega a decir cuál de las dos gana. En la práctica los analizadores discrepan: casi todos se quedan con la última, algunos con la primera, unos pocos rechazan el documento. Un formateador que emite una de ellas en silencio ha tomado esa decisión por ti, y ha escondido el hecho mucho más útil de que había dos — que casi siempre es un error del archivo, y uno que querrías ver.

Cuando el archivo no se deja analizar

Casi todo el JSON que falla no es exótico. Es una de unas seis cosas, y el error te dice cuál si te dice dónde está en términos que puedas encontrar. Un desplazamiento como posición 4193 no lo es; una línea y una columna sí.

Uno que no es un error y lo parece: un archivo que empieza con una marca de orden de bytes. Es invisible en casi todos los editores, no es espacio en blanco, y hace que el primerísimo carácter del documento sea inesperado. Si el error está en la línea 1, columna 1 de un archivo que se ve perfecto, es eso.

La misma herramienta con un documento roto: un error que da la línea y la columna de una coma sobrante, y el panel de entrada mostrando la línea culpable.
Cuando no se puede leer, el mensaje dice dónde. Una coma sobrante es la causa más común y la más difícil de ver a simple vista.

Minificar, y lo poco que suele ganar

Exprimir los espacios es la misma operación al revés, y conviene ser realista sobre lo que te compra. Los espacios se repiten muchísimo, y todo servidor y todo navegador entre tú y quien lee ya comprime la respuesta con gzip o Brotli, que son muy buenos precisamente con ese tipo de repetición.

Así que el JSON minificado suele ser un treinta por ciento más pequeño como archivo y solo un pequeño porcentaje más pequeño por el cable. Donde sí se gana el sueldo es en los sitios sin compresión delante: un valor en una columna de base de datos, un campo en una línea de registro, una carga dentro de un código QR, o un documento que vas a meter en Base64 dentro de una cabecera.

Lo que cuesta es legibilidad, y si el archivo está en un repositorio te cuesta también los diffs — un archivo de una línea cambia entero cada vez que cambia cualquier cosa dentro. Minifica al salir de tu editor, no al entrar.

Ordenar las claves, y cuándo no

Ordenar las claves de cada objeto se ofrece aquí como opción en vez de aplicarse por defecto, porque es un cambio real en el archivo y su valor depende por completo de qué vas a hacer después.

Ayuda cuando comparas dos documentos que deberían decir lo mismo — la configuración de dos entornos, una respuesta de una API antes y después de un cambio — y uno de ellos lista sus claves en otro orden. Ordenar los dos antes convierte un diff de todo en un diff de las dos líneas que realmente difieren.

Estorba cuando el orden estaba haciendo algo. Un package.json tiene convenciones sobre qué va primero; una configuración escrita a mano suele agrupar ajustes relacionados; y un archivo cuyas claves ordenó una herramienta y luego se confirmó produce un único commit enorme y sin sentido. Ordena una copia, no el original.

Un detalle que conviene saber: aquí se ordena por cómo se leen las claves y no por sus puntos de código, así que item2 va antes que item10 y no después. Ordenar por punto de código es lo que pone item10 en medio de los que empiezan por uno, lo cual es técnicamente correcto e inútil para quien lee.

Comparar dos archivos JSON

La forma fiable es formatear los dos igual primero. Dos documentos que dicen lo mismo pueden diferir en todas las líneas si uno estaba minificado y el otro no, y no hay diff que vea más allá de eso.

Así que: formatea el primero, formatea el segundo, y luego compara los dos resultados. Los tres pasos están aquí en la misma página — la pestaña Comparar comparte la casilla con Formatear justamente por esto. Si además listan sus claves en órdenes distintos, ordénalas en los dos mientras los formateas y la comparación se reduce a la diferencia que buscabas.

La parte que nadie pone en la página

Busca un formateador de JSON y encontrarás docenas de sitios con una casilla. Pegar en esa casilla es subir. Lo que hubiera en tu portapapeles — una respuesta de una API con la dirección de un cliente dentro, un archivo de configuración con una cadena de conexión, un token que estabas depurando — se ha enviado a una máquina que no controlas, y ahora es su archivo de registro, su informe de error y su copia de seguridad.

Esto no es una hipótesis sobre mala fe. Un sitio con toda la buena intención sigue guardando registros de acceso, sigue teniendo analítica, y sigue teniendo un proveedor de alojamiento. Los datos más seguros son los que no salieron nunca, y para un trabajo que es puramente manipulación de texto no hay razón alguna para que salgan.

Dos comprobaciones, y sirven para cualquier sitio que haga esta afirmación, no solo para este:

  1. Abre las DevTools, mira la pestaña de red y formatea algo. Si tu texto se está enviando, hay una petición que lo lleva. Ninguna otra cosa puede ser cierta al mismo tiempo.
  2. Desconéctate de internet y prueba otra vez. A una herramienta que hace el trabajo en tu navegador no le afecta. Una herramienta que manda tu texto a algún sitio deja de funcionar, de inmediato y del todo.

Hay una versión más larga de las dos, con otras dos comprobaciones, en ¿es seguro subir archivos?

¿Y el YAML, el XML y los demás?

La misma página lee XML, HTML, CSS y YAML, y convierte entre JSON y el primero y el último de esos. Dos cosas merecen traerse de arriba, porque son el mismo argumento con otro traje: