How to read a JSON Response body

142 views
Skip to first unread message

st ov

unread,
Mar 20, 2018, 1:37:40 PM3/20/18
to golang-nuts
For JSON responses, is it more appropriate to use
  
json.Unmarshal(resp.Body, &data)

or

json.NewDecoder(resp.Body).Decode(&data)

or

b, _ := ioutil.ReadAll(resp.Body)
json.Unmarshal(b, &data)


What are the uses for each?
Does this differ from how you would read non-JSON responses?

Alex Efros

unread,
Mar 20, 2018, 2:26:18 PM3/20/18
to golang-nuts
Hi!

On Tue, Mar 20, 2018 at 10:37:40AM -0700, st ov wrote:
> json.Unmarshal(resp.Body, &data)

This one is invalid.

> json.NewDecoder(resp.Body).Decode(&data)
>
> or
>
> b, _ := ioutil.ReadAll(resp.Body)
> json.Unmarshal(b, &data)

In the ReadAll case you'll have to allocate []byte in memory to store
whole response, which is expected to be less effective than NewDecoder
case which may use less memory to process whole response.

Another difference is NewDecoder() may stop reading before EOF in case it
notice syntax error or if response contain more than one JSON element.

In short, use NewDecoder when you've io.Reader, and Unmarshal when you've
[]byte.

--
WBR, Alex.

Jonathan Yu

unread,
Mar 20, 2018, 4:21:15 PM3/20/18
to golang-nuts
Something to consider is that NewDecoder supports JSON streams, e.g. {"a": "b"}{"c": "d"}{"e": "f" }

Each call to Decode will decode one object from the stream, but the underlying reader is not necessarily guaranteed to be at EOF. See: https://ahmet.im/blog/golang-json-decoder-pitfalls/

I don't have the same conclusion as the article, and think that using the stream syntax is often useful, but care must be taken to ensure that the stream is fully consumed and closed.

Jonathan


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Jonathan Yu @jawnsy on LinkedInTwitterGitHubFacebook
“Ever tried. Ever failed. No matter. Try again. Fail again. Fail better.” — Samuel Beckett, Worstward Ho (1983) 

“In an adaptive environment, winning comes from adapting to change by continuously experimenting and identifying new options more quickly and economically than others. The classical strategist's mantra of sustainable competitive advantage becomes one of serial temporary advantage.” — Navigating the Dozens of Different Strategy Options (HBR)

st ov

unread,
Mar 20, 2018, 11:08:58 PM3/20/18
to golang-nuts
Thanks!

So using ioutil.ReadAll() followed by json.Unmarshal() can still be used, as this official example in the documentation shows


But is less efficient than using json.Decoder().Decode() itself

How should I handle the EOF case?
Reply all
Reply to author
Forward
0 new messages