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.