Noms de clé JSON en minuscules avec JSON Marshal dans Go

175

Je souhaite utiliser le "encoding/json"package pour marshaler une structure déclarée dans l'un des packages importés de mon application.

Par exemple.:

type T struct {
    Foo int
}

Comme il est importé, tous les champs disponibles (exportés) de la structure commencent par une lettre majuscule. Mais je souhaite avoir des noms de clé en minuscules:

out, err := json.Marshal(&T{Foo: 42})

aura pour résultat

{"Foo": 42}

mais je souhaite avoir

{"toto": 42}

Est-il possible de contourner le problème de manière simple?

ANisus
la source
5
@Zippoxer: Je dirais: une clé dans un protocole de communication client / serveur strictement défini en minuscules. Eh bien, dans mon cas, cela n'a pas d'importance puisque j'ai moi-même défini le protocole ... mais en théorie du moins? Mais je sais que c'est principalement moi qui passe trop de temps sur un petit détail ridicule.
ANisus
Ne vous excusez pas. Vous n'êtes pas idiot, le langage qui n'accepte pas la spécification complète de json est le idiot (bien que le problème soit facilement résolu, comme ci-dessous).
Jehan
@ANisus: J'ai mal interprété votre question concernant les noms de clé de structure, pas les noms de clé JSON. Retiré le vote.
Flimzy

Réponses:

266

Jetez un œil à la documentation pour encoder / json.Marshal . Il traite de l'utilisation des balises de champ struct pour déterminer comment le json généré est formaté.

Par exemple:

type T struct {
    FieldA int    `json:"field_a"`
    FieldB string `json:"field_b,omitempty"`
}

Cela générera JSON comme suit:

{
    "field_a": 1234,
    "field_b": "foobar"
}
Jimt
la source
8
Balises de champ? Oh mon ... J'ai manqué toute cette partie lors de la recherche dans les documents. Je cherchais des drapeaux, des fonctions ou d'autres paramètres. Eh bien, c'est la réponse exacte que je cherchais! Et en plus, j'ai un nouveau concept Go à apprendre: les balises de champ :)
ANisus
Ils sont très pratiques. Vous pouvez y accéder au moment de l'exécution via le reflectpackage.
jimt
Ouais, quand je travaille avec la réflexion, je vois comment avoir un moyen d'ajouter des métadonnées à un champ peut être une chose merveilleuse! Btw, juste essayé la réponse. Fonctionne comme un charme.
ANisus
5
Je viens juste de commencer à maudire le langage go - comme c'est stupide, pourquoi feraient-ils les champs avec des lettres minuscules dans le JSON généré, etc. J'ai même sauté et expliqué à ma copine pourquoi je suis si excité: D C'est tellement cool :)))
nyxz
11
Assurez-vous qu'il n'y a pas d'espace entre les deux points et le premier guillemet de la balise! Utilisez à la json:"some_tag"place de json: "some_tag". J'ai été mordu par ça pendant un moment.
David Morales
8

Vous pouvez créer votre propre structure avec les clés que vous souhaitez exporter et leur attribuer les balises json appropriées pour les noms en minuscules. Ensuite, vous pouvez copier la structure souhaitée dans la vôtre avant de l'encoder en JSON. Ou si vous ne voulez pas vous soucier de créer une structure locale, vous pouvez probablement en créer un map[string]interface{}et l'encoder.

Lily Ballard
la source
La chose idiote est que l'autre paquet (contenant les types) est aussi le mien. Mais, oui, j'ai probablement regardé aveuglément le fait que ce doit être une structure. Utiliser a map[string]interface{}fonctionnerait tant que je ne me retrouverai pas avec des objets / structures imbriqués
ANisus
1
@ANisus: Oh, ma réponse était basée sur le fait que vous ne contrôliez pas la définition de la structure. La réponse de Jimt est certainement ce que vous voulez.
Lily Ballard
Ouais, je ne savais pas si c'était un package externe ou non. Mais votre réponse est toujours pertinente et utile dans les cas où vous ne contrôlez pas les définitions.
ANisus