Je développe un client API sur lequel je dois encoder une charge JSON à la demande et décoder un corps JSON à partir de la réponse.
J'ai lu le code source de plusieurs bibliothèques et, d'après ce que j'ai vu, j'ai deux possibilités pour coder et décoder une chaîne JSON.
Utilisez json.Unmarshal
en passant la chaîne de réponse complète
_data, err := ioutil.ReadAll(resp.Body)
if err == nil && data != nil {
err = json.Unmarshal(data, value)
}
_
ou en utilisant _json.NewDecoder.Decode
_
_err = json.NewDecoder(resp.Body).Decode(value)
_
Dans mon cas, s’agissant de réponses HTTP implémentant _io.Reader
_, la deuxième version semble nécessiter moins de code, mais depuis que j’ai vu les deux, je me demande s’il est préférable d’utiliser une solution plutôt que le autre.
De plus, la réponse acceptée de cette question dit
Veuillez utiliser _
json.Decoder
_ au lieu de _json.Unmarshal
_.
mais il n'a pas mentionné la raison. Devrais-je vraiment éviter d'utiliser _json.Unmarshal
_?
Cela dépend vraiment de votre contribution. Si vous examinez la mise en oeuvre de la méthode Decode
de json.Decoder
, elle met en mémoire tampon la valeur JSON entière en mémoire avant de la démultiplier dans une valeur Go. Ainsi, dans la plupart des cas, l’utilisation de la mémoire ne sera plus efficace (même si cela pourrait facilement changer dans une future version du langage).
Donc, une meilleure règle de base est la suivante:
json.Decoder
si vos données proviennent d’un flux io.Reader
, ou si vous devez décoder plusieurs valeurs d’un flux de données.json.Unmarshal
si vous avez déjà les données JSON en mémoire.Pour le cas de la lecture d'une requête HTTP, je choisirais json.Decoder
puisque vous lisiez à partir d'un flux.