Conversor de JSON a Struct de Go

Pega un objeto JSON (o un array JSON) para generar automáticamente las definiciones de struct de Go correspondientes con etiquetas json.

Convertir JSON en structs de Go

Recibir la respuesta de una API en Go obliga a escribir un struct que se corresponda con el JSON, junto con sus etiquetas json. Con un puñado de campos no cuesta nada, pero **en cuanto el anidamiento se profundiza, recorrer la jerarquía mientras se inventan nombres de tipo se convierte en el trabajo mismo.** Esta herramienta genera el juego completo de definiciones, estructuras anidadas incluidas, sin más que el JSON que usted pegue.

**Conviene tener presente, eso sí, que lo que sale es un tipo deducido de una sola muestra.** Las claves que no aparecieran en ella faltarán, como es natural, y cualquier campo cuyo valor fuese `null` pasa a ser `interface{}`, ya que Go no tiene un primitivo anulable al que asignarlo. Cuando todos los elementos de un arreglo son objetos, las claves se fusionan en un único struct y **las presentes solo en algunos elementos quedan marcadas con `omitempty`.** Convertir la salida en un struct de producción da por supuesto que usted cotejará estas deducciones con la especificación real de la API y las corregirá.

Cómo convertir

  1. Pegue el JSON Sirve igual un objeto que un arreglo; la respuesta de una API entra tal como llegó.
  2. Nombre el tipo raíz Empieza como `Root`. **Los nombres de los tipos anidados salen solos, convirtiendo cada nombre de propiedad a notación Pascal.**
  3. Revise los structs generados Las definiciones aparecen en orden jerárquico con sus etiquetas json ya puestas.
  4. Cópielos y déles forma Pase el resultado por `gofmt` y vuelva sobre lo que quedó como `interface{}` o sobre lo que debería ser un puntero, siguiendo la especificación real.

Consejos para aprovecharla mejor

  • Cuando todos los elementos de un array son objetos, sus claves se combinan en un solo struct. Las claves que faltan en algunos elementos reciben automáticamente una etiqueta json `omitempty`.
  • El nombre del tipo raíz es "Root" por defecto, pero puedes cambiarlo por el que prefieras. Los nombres de struct para objetos anidados se generan automáticamente convirtiendo el nombre de la propiedad a PascalCase.
  • El valor null de JSON se genera como `interface{}` porque Go no tiene un tipo primitivo nativo que admita null. Considera usar un tipo puntero si necesitas un manejo más estricto.
  • El resultado es un borrador con columnas ligeramente alineadas. Pasarlo por `gofmt` después de pegarlo lo ajustará al estilo estándar de tu proyecto.
  • Pega tal cual una respuesta JSON de ejemplo de tu API para obtener rápidamente un borrador del struct de respuesta que usarás en tu código Go.

Cuándo resulta útil

Al empezar un cliente de API

Pegar la respuesta de ejemplo de la documentación le da al instante un primer borrador del struct receptor.

Al cargar un archivo de configuración

Cuando los ajustes se guardan en JSON, la estructura puede transcribirse directamente a un tipo.

Al descifrar la especificación de un tercero

**Un JSON profundamente anidado se entiende mucho mejor una vez desplegado como un conjunto de structs.**

Al preparar datos de prueba

Deducir primero los tipos de una respuesta real reduce el riesgo de desajuste cuando llegue el momento de escribir simulaciones.

Términos del mapeo de tipos en Go

Struct
El tipo de Go que agrupa varios campos. Se corresponde con un objeto de JSON.
Etiqueta json
La anotación escrita tras un campo con la forma `json:"user_id"`, que **indica al codificador cómo se alinea el nombre del campo de Go con la clave del JSON.**
Omitempty
Opción de la etiqueta json que **deja el campo fuera de la salida cuando su valor es el valor cero.** No significa que el campo admita nulos, distinción que conviene retener.
Interface{}
Tipo que acepta cualquier valor. Los nulos del JSON y los campos de tipo cambiante aterrizan aquí, lo que **lo convierte en una buena señal de los puntos que revisar tras la generación.**
Notación Pascal
La convención de poner en mayúscula cada palabra, como en `UserId`. En Go **esa mayúscula inicial lleva además el significado de exportarse fuera del paquete.**
Tipo puntero
Un tipo escrito como `*string`. Es lo que se emplea cuando la ausencia de valor debe distinguirse de una cadena vacía.

Preguntas frecuentes

Escribir un struct a mano a partir de una respuesta de ejemplo lleva tiempo y es propenso a errores: es fácil equivocarse al convertir un nombre de campo u olvidar una etiqueta json, sobre todo con objetos muy anidados. Generarlo automáticamente ahorra mucho tiempo de implementación y evita estos errores.

Las claves JSON (en snake_case o camelCase) se convierten a PascalCase, con la primera letra en mayúscula, para obtener nombres de campo exportables en Go. La clave JSON original se conserva tal cual en la etiqueta json (`json:"clave_original"`), por lo que la codificación y decodificación siguen funcionando correctamente.

Un valor null se genera como el tipo `interface{}`. Una clave que solo aparece en algunos elementos de un array recibe automáticamente una etiqueta json `omitempty`, pero el tipo de Go en sí solo toma su valor cero, así que considera usar un puntero si necesitas distinguir "ausente" de "cero".

Un número JSON con punto decimal se clasifica como `float64`, y uno sin punto decimal como `int`. Como la notación numérica de JSON solo conserva los dígitos, ajusta manualmente el tipo después para valores lo bastante grandes como para necesitar `int64`.

Como Go no tiene tipos unión, una clave cuyo tipo difiere entre elementos recae en `interface{}`. Tendrás que usar una aserción de tipo en tiempo de ejecución para determinar el tipo real del valor.
Tool-kun

A propósito — Por qué Go combina structs con etiquetas json

Go es un lenguaje de tipado estático, y al trabajar con JSON, el paquete `encoding/json` de la biblioteca estándar depende de la correspondencia entre los campos del struct y sus etiquetas json para codificar y decodificar datos. Escribir a mano un struct para la forma de la respuesta de una API externa es una tarea repetitiva que crece cada vez que se añade un campo, y se ha repetido en muchos proyectos de Go.

Esta herramienta analiza la estructura de un JSON de ejemplo y genera automáticamente las definiciones de struct y las etiquetas json correspondientes, reduciendo ese trabajo repetitivo. Una herramienta conocida en este mismo espacio es quicktype, que admite convertir a tipos de varios lenguajes; pero para el caso más simple de pegar una respuesta de API de ejemplo y obtener rápidamente un struct de Go, una herramienta enfocada en una sola tarea tiene su propia comodidad.

Como Go no tiene ninguna característica del lenguaje para hacer opcional un campo de struct, el enfoque habitual para los campos JSON que podrían faltar es añadir `omitempty` a la etiqueta json, o usar un tipo puntero (como `*string`) para distinguir un valor cero de "ningún valor". El struct generado es solo una inferencia mecánica a partir de la estructura, así que tratar la posibilidad de null y los futuros cambios de la API como algo que se debe verificar y ajustar a mano contra la especificación real es la práctica habitual.