Traitement JSON avec Go

Les bases du marshaling et du démarshaling JSON

JSON signifieJavaScriptNotation d'objets, et c'est un moyen très pratique d'échanger des données structurées. Et c'est très populaire, en particulier lors de l'interaction avec les API.

Go a une prise en charge de haut niveau pour JSON dans sa bibliothèque standard, avecleencoding/jsonpaquet.

Comparé aux langages de typage lâche, le décodage JSON est plus compliqué. En JavaScript, tout ce que vous avez à faire estJSON.parse(). Python ajson.loads(), et PHP ajson_decode(). Ils ne font que vider les valeurs sans problème, mais étant fortement typé Go, vous devez faire un peu plus de travail pour faire correspondre les types.

JSON a 3 types de base:booléens,Nombres,cordes, combiné en utilisanttableauxetobjetspour construire des structures complexes.

Appels de terminologie de Gomaréchalle processus de génération d'une chaîne JSON à partir d'une structure de données, etnon maréchall'acte d'analyser JSON en une structure de données.

Une chaîne JSON

input := `{"firstname": "Bill", "surname": "Gates"}`

Unmarshal JSON

Voici un exemple JSON tiré deMDN de Mozilla

{
  "squadName": "Super hero squad",
  "homeTown": "Metro City",
  "formed": 2016,
  "secretBase": "Super tower",
  "active": true,
  "members": [
    {
      "name": "Molecule Man",
      "age": 29,
      "secretIdentity": "Dan Jukes",
      "powers": [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    },
    {
      "name": "Madame Uppercut",
      "age": 39,
      "secretIdentity": "Jane Wilson",
      "powers": [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    },
    {
      "name": "Eternal Flame",
      "age": 1000000,
      "secretIdentity": "Unknown",
      "powers": [
        "Immortality",
        "Heat Immunity",
        "Inferno",
        "Teleportation",
        "Interdimensional travel"
      ]
    }
  ]
}

Comment pouvons-nous l'analyser dans une structure de données Go? Nous avons besoin d'une structure de données correspondante, bien sûr. Nous avons 5 types de base et un tableau d'objets. Commençons par les types de base:

type squad struct {
    SquadName string
    HomeTown string
    Formed int
    SecretBase string
    Active bool
}

Nous devons définir le JSON comme un[]byte, comme ça:

input := []byte(`
    {
        "squadName": "Super hero squad",
        [...]
    }
`)

Et nous pouvons démarseler le JSON en une instance d'escouade:

s := squad{}
err := json.Unmarshal(input, &s)
if err != nil {
    panic(err)
}
fmt.Printf("%v", s)

Cela imprimera

{Super hero squad Metro City 2016 Super tower true}

jouer

Remarquez que nous n'avons aucune erreur se plaignant de la correspondance manquante entre les valeurs JSON et notre structure, elles sont ignorées.

Assurons-nous que json.Unmarshal () nous obtiendra tous les champs, avec:

type squad struct {
	SquadName  string
	HomeTown   string
	Formed     int
	SecretBase string
	Active     bool
	Members    []Member
}

type Member struct { Name string Age int SecretIdentity string Powers []string }

jouer

N'oubliez pas d'avoir des propriétés publiques (majuscules) dans vos structures.

Renommer les noms de champs JSON

Dans ce cas, tout allait bien car le JSON avait des noms de fichiers compatibles. Que faire si vous souhaitez mapper le JSON à d'autres champs de votre structure?

Par exemple, que se passe-t-il si le nom du membre est passé commemember_name, mais vous voulez qu'il soit stocké dansNameau lieu?

Utilisez cette syntaxe:

type Member struct {
	Name string `json:"member_name"`
}

Ignorer les champs JSON

Utilisez cette syntaxe:

type Member struct {
	Name string `json:"-"`
}

et le champ Nom sera ignoré lors du marshaling / unmarshaling.

Conversion des types de champs JSON

Vous pouvez utiliser des balises pour annoter le type dans lequel le JSON sera converti:

type Member struct {
    Age       int `json:"age,string"`
}

La structure membre a unAgepropriété représentée comme unint. Et si vous voulez que ce soit unstringà la place, mais JSON passe unint?

Utilisez l'annotation de type:

type Member struct {
    Age       json.Number `json:"age,Number"`
}

Le type Number est un alias pourstring.

En savoir plus sur les balises dansGo Tags expliqué

Maréchal JSON

Nous pourrions maintenant vouloir créer une chaîne JSON à partir de nos structures de données. Par exemple, il peut s'agir d'un programme qui prend un code de pays et renvoie les détails du pays correspondant au format JSON.

package main

import ( “encoding/json” “fmt” )

type country struct { Name string }

func main() { country_code := “US”

<span style="color:#a6e22e">the_country</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">country</span>{}

<span style="color:#66d9ef">switch</span> <span style="color:#a6e22e">country_code</span> {
<span style="color:#66d9ef">case</span> <span style="color:#e6db74">"US"</span>:
	<span style="color:#a6e22e">the_country</span>.<span style="color:#a6e22e">Name</span> = <span style="color:#e6db74">"United States"</span>
}

<span style="color:#a6e22e">c</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Marshal</span>(<span style="color:#a6e22e">the_country</span>)
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
	panic(<span style="color:#a6e22e">err</span>)
}

<span style="color:#75715e">// c is now a []byte containing the encoded JSON

fmt.Print(string(c)) }

jouer

Une fois exécuté, ce programme imprimera{"Name":"United States"}.

json.Marshal()renvoie un[]byte, nous devons donc le convertir en chaîne en le passant àfmt.Print(), sinon vous verrez une liste de nombres apparemment dénués de sens (mais ils sont significatifs, car ce sont les octets réels qui composent la chaîne).

json.Marshal()traitera correctement les types de base et composites tels que les tranches et les cartes.

Lire la suite

Lire la suitesur le blog Goet enleencoding/jsonpackage doc


Plus de tutoriels go: