Tworzę klienta API, w którym muszę zakodować ładunek JSON na żądanie i zdekodować treść JSON na podstawie odpowiedzi.
Przeczytałem kod źródłowy z kilku bibliotek i z tego, co widziałem, mam zasadniczo dwie możliwości kodowania i dekodowania łańcucha JSON.
Użyj json.Unmarshal
przekazywania całego ciągu odpowiedzi
data, err := ioutil.ReadAll(resp.Body)
if err == nil && data != nil {
err = json.Unmarshal(data, value)
}
lub za pomocą json.NewDecoder.Decode
err = json.NewDecoder(resp.Body).Decode(value)
W moim przypadku, gdy mamy do czynienia z odpowiedziami HTTP, które się implementują io.Reader
, wydaje się, że druga wersja wymaga mniej kodu, ale skoro widziałam obie, zastanawiam się, czy jest jakaś preferencja, czy powinienem użyć rozwiązania, czy innej.
Co więcej, przyjęta odpowiedź na to pytanie mówi
Użyj
json.Decoder
zamiastjson.Unmarshal
.
ale nie podał przyczyny. Czy naprawdę powinienem unikać używania json.Unmarshal
?
ioutil.ReadAll
jest prawie zawsze zły pomysł. Nie jest to związane z twoim celem, ale wymaga posiadania wystarczającej ilości ciągłej pamięci, aby przechowywać wszystko, co może zejść z potoku, nawet jeśli ostatnie 20 TB odpowiedzi przypada po ostatnim }
w twoim JSON.
io.LimitReader
aby temu zapobiec.