Convertisseur JSON vers Struct Go

Collez un objet JSON (ou un tableau JSON) pour générer automatiquement les définitions de struct Go correspondantes avec leurs balises json.

Transformer du JSON en structures Go

Recevoir une réponse d'API en Go suppose d'écrire une structure correspondant au JSON, assortie de ses balises json. Avec une poignée de champs, l'affaire est vite réglée, mais **dès que l'imbrication s'approfondit, parcourir la hiérarchie tout en inventant des noms de type devient à soi seul le travail.** Cet outil produit l'ensemble des définitions, structures imbriquées comprises, à partir du seul JSON que vous collez.

**Gardez toutefois à l'esprit que ce qui sort est un type déduit d'un unique échantillon.** Les clés qui n'y figuraient pas manqueront, naturellement, et tout champ dont la valeur était `null` devient `interface{}`, Go ne disposant d'aucun type primitif nullable où le loger. Lorsque tous les éléments d'un tableau sont des objets, leurs clés sont fusionnées en une seule structure et **celles qui ne figurent que dans certains éléments reçoivent `omitempty`.** Faire de cette sortie une structure de production suppose que vous confronterez ces déductions à la spécification réelle de l'API pour les corriger.

Comment convertir

  1. Collez le JSON Un objet convient aussi bien qu'un tableau ; une réponse d'API s'y place telle qu'elle est arrivée.
  2. Nommez le type racine Il s'appelle d'abord `Root`. **Les noms des types imbriqués se déduisent seuls, chaque nom de propriété étant passé en notation Pascal.**
  3. Parcourez les structures produites Les définitions se présentent dans l'ordre des niveaux, leurs balises json déjà posées.
  4. Copiez puis peaufinez Passez le résultat à `gofmt`, puis revenez sur ce qui est devenu `interface{}` ou sur ce qui devrait être un pointeur, en suivant la spécification réelle.

Astuces pour en tirer le meilleur parti

  • Lorsque tous les éléments d'un tableau sont des objets, leurs clés sont fusionnées en une seule struct. Les clés absentes de certains éléments reçoivent automatiquement la balise json `omitempty`.
  • Le nom du type racine est "Root" par défaut, mais vous pouvez le renommer comme vous le souhaitez. Les noms de struct pour les objets imbriqués sont générés automatiquement en convertissant le nom de la propriété en PascalCase.
  • La valeur null de JSON est générée sous forme de `interface{}`, car Go n'a pas de type primitif natif acceptant null. Envisagez un type pointeur si vous avez besoin d'un traitement plus strict.
  • Le résultat est un brouillon aux colonnes légèrement alignées. Le passer dans `gofmt` après collage l'alignera sur le style standard de votre projet.
  • Collez telle quelle une réponse JSON d'exemple de votre API pour obtenir rapidement une ébauche de la struct de réponse utilisée dans votre code Go.

Dans quels cas s'en servir

Pour démarrer un client d'API

Coller la réponse d'exemple de la documentation vous donne aussitôt une première ébauche de la structure réceptrice.

Pour lire un fichier de configuration

Quand les réglages tiennent en JSON, leur agencement se transcrit directement en un type.

Pour déchiffrer la spécification d'un tiers

**Un JSON profondément imbriqué devient bien plus lisible une fois déplié en un jeu de structures.**

Pour préparer des données de test

Déduire d'abord les types d'une réponse réelle réduit le risque de méprise au moment d'écrire des doublures.

Vocabulaire du mappage de types en Go

Structure
Le type Go qui rassemble plusieurs champs. Il correspond à un objet en JSON.
Balise json
L'annotation placée après un champ sous la forme `json:"user_id"`, qui **indique à l'encodeur comment le nom du champ Go s'aligne sur la clé du JSON.**
Omitempty
Option de la balise json qui **retire le champ de la sortie lorsque sa valeur est la valeur nulle du type.** Elle ne rend pas le champ nullable, distinction qu'il vaut mieux retenir.
Interface{}
Type qui accepte n'importe quelle valeur. Les nuls du JSON et les champs au type mouvant y atterrissent, ce qui **en fait un repère commode des endroits à revoir après la génération.**
Notation Pascal
L'usage de mettre chaque mot en capitale initiale, comme dans `UserId`. En Go **cette majuscule de tête porte en outre le sens d'être exportée hors du paquet.**
Type pointeur
Un type écrit `*string`. On y recourt lorsque l'absence de valeur doit se distinguer d'une chaîne vide.

Questions fréquentes

Écrire une struct à la main à partir d'une réponse d'exemple prend du temps et est source d'erreurs : il est facile de se tromper dans la conversion d'un nom de champ ou d'oublier une balise json, surtout avec des objets très imbriqués. La génération automatique fait gagner beaucoup de temps d'implémentation et évite ces erreurs.

Les clés JSON (en snake_case ou camelCase) sont converties en PascalCase avec une majuscule initiale, ce qui donne des noms de champs exportables en Go. La clé JSON d'origine est conservée telle quelle dans la balise json (`json:"clé_originale"`), si bien que l'encodage et le décodage continuent de fonctionner correctement.

Une valeur null est générée sous le type `interface{}`. Une clé présente seulement dans certains éléments d'un tableau reçoit automatiquement la balise json `omitempty`, mais le type Go lui-même ne prend que sa valeur zéro : envisagez un type pointeur si vous devez distinguer "absent" de "zéro".

Un nombre JSON avec un point décimal est classé en `float64`, et sans point décimal en `int`. Comme la notation numérique de JSON ne conserve que les chiffres, ajustez manuellement le type ensuite pour les valeurs assez grandes pour nécessiter `int64`.

Comme Go n'a pas de types union, une clé dont le type diffère selon les éléments retombe sur `interface{}`. Il faudra alors utiliser une assertion de type à l'exécution pour déterminer le type réel de la valeur.
Tool-kun

Anecdote — pourquoi Go associe structs et balises json

Go est un langage à typage statique, et lorsqu'il manipule du JSON, le paquet `encoding/json` de la bibliothèque standard s'appuie sur la correspondance entre les champs d'une struct et leurs balises json pour encoder et décoder les données. Écrire à la main une struct pour la forme de réponse d'une API externe est une tâche répétitive qui s'alourdit à chaque champ ajouté, et elle revient sans cesse dans de nombreux projets Go.

Cet outil analyse la structure d'un JSON d'exemple et génère automatiquement les définitions de struct et les balises json correspondantes, réduisant ainsi ce travail répétitif. Un outil connu dans le même domaine est quicktype, qui prend en charge la conversion vers des types de plusieurs langages ; mais pour le cas plus simple où l'on veut coller une réponse d'API d'exemple et obtenir rapidement une struct Go, un outil dédié à cette seule tâche a aussi son propre confort.

Comme Go ne dispose d'aucune fonctionnalité de langage pour rendre un champ de struct optionnel, l'approche courante pour les champs JSON susceptibles d'être absents consiste à ajouter `omitempty` à la balise json, ou à utiliser un type pointeur (comme `*string`) pour distinguer une valeur zéro de "aucune valeur". La struct générée n'est qu'une déduction mécanique à partir de la structure : il est donc d'usage de vérifier et d'ajuster manuellement la question du nullable et des évolutions futures de l'API par rapport à la spécification réelle.