2. Decoding JSON
When you receive JSON data in an HTTP response body, it's a stream of bytes. In Go it's common to decode that JSON directly into a struct (or slice of structs) using the standard encoding/json package rather than converting bytes to string.
Example JSON
[
{
"id": "001-a",
"title": "Unspaghettify code",
"estimate": 9001
}
]Struct with JSON tags
type Issue struct {
Id string `json:"id"`
Title string `json:"title"`
Estimate int `json:"estimate"`
}Notes about tags and exported fields
The tag
json:"id"maps the JSONidfield to the Go field.Tags are wrapped in backticks
`.Only exported (capitalized) fields are decoded. Unexported fields (lowercase) will be ignored by the decoder.
Decoding from an HTTP response body
Using the decoded data
Complete example
JSON tag options
Common patterns
Single object: decode into a struct value.
Array of objects: decode into a slice of structs.
Nested objects: define nested struct types and decode accordingly.
Alternative: json.Unmarshal
When to use each:
json.NewDecoder β for streams (HTTP responses, files)
json.Unmarshal β for byte slices already in memory
Error handling example
Key takeaways:
JSON tags map JSON fields to struct fields:
json:"field_name"Fields must be exported (capitalized) to decode
Use
&when decoding so the decoder can modify the variablejson.NewDecoderfor streams,json.Unmarshalfor byte slicesAlways check errors when decoding
Quick reference
Assignment
Follow these steps to decode the response data directly into a slice of issues and return it. If any error occurs return a nil slice and the error.
Import the json package:
add "encoding/json" to your imports
Create a nil slice of items:
var issues []Issue
Create a new *json.Decoder using json.NewDecoder:
decoder := json.NewDecoder(res.Body)
Decode the response body using Decode:
if err := decoder.Decode(&issues); err != nil { return nil, err }
Return the slice of issues:
return issues, nil
Solution example