Je développe un client API dans lequel je dois encoder une charge utile JSON sur 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 essentiellement deux possibilités pour encoder et décoder une chaîne JSON.
Utilisez en json.Unmarshal
passant la chaîne de réponse entière
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, lorsqu'il s'agit de réponses HTTP qui implémentent io.Reader
, la deuxième version semble nécessiter moins de code, mais comme j'ai vu les deux, je me demande s'il y a une préférence si je devrais utiliser une solution plutôt que l'autre.
De plus, la réponse acceptée à cette question dit
Veuillez utiliser à la
json.Decoder
place dejson.Unmarshal
.
mais il n'a pas mentionné la raison. Dois-je vraiment éviter d'utiliser json.Unmarshal
?
ioutil.ReadAll
est presque toujours la mauvaise chose à faire. Cela n'est pas lié à votre objectif, mais vous oblige à disposer de suffisamment de mémoire contiguë pour stocker tout ce qui pourrait arriver dans le tuyau, même si les 20 derniers To de réponse sont après le dernier}
de votre JSON.io.LimitReader
pour éviter cela.Réponses:
Cela dépend vraiment de votre contribution. Si vous regardez l'implémentation de la
Decode
méthode dejson.Decoder
, elle met en mémoire tampon toute la valeur JSON en mémoire avant de la démarshalling en une valeur Go. Donc, dans la plupart des cas, la mémoire ne sera plus efficace (bien que cela puisse 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'unio.Reader
flux ou si vous devez décoder plusieurs valeurs à partir 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 à partir d'une requête HTTP, je choisirais
json.Decoder
car vous lisez évidemment à partir d'un flux.la source
Buffered
méthode est là pour vous permettre de voir toutes les données supplémentaires qui ont été lues dans le tampon interne après la valeur.