Decoding JSON into Structs in Go

Introduction to Decoding JSON in Go

Welcome back! In the previous lesson, you learned how to encode Go structs into JSON format, a process known as marshaling. This skill is crucial for sending data to APIs, as JSON is the primary data format for most web services. Now, we will focus on the reverse process: decoding JSON data into Go structs, also known as unmarshaling. This is an essential skill for receiving and processing data from APIs. By the end of this lesson, you will be able to seamlessly convert JSON data into Go structs, preparing you for effective API communication.

Understanding JSON to Struct Mapping

When decoding JSON into Go structs, it's important to understand how JSON keys map to struct fields. In Go, this is achieved using struct tags. Struct tags are annotations that specify how struct fields should be encoded or decoded. For example, if you have a JSON key named "title," you can map it to a struct field using a tag like json:"title". This ensures that the JSON data is correctly mapped to the corresponding fields in your Go struct.

Example: Decoding JSON into Go Structs

Let's walk through an example to see how decoding JSON into Go structs works in practice. We'll use the Todo struct, which you are already familiar with from previous lessons. Here's a complete example that demonstrates how to fetch JSON data from an API and decode it into a Go struct.

Step 1: Defining the Todo Struct

type Todo struct {
    Title       string `json:"title"`
    Done        bool   `json:"done"`
    Description string `json:"description"`
}

The Todo struct defines the expected structure of the JSON data. The struct tags (json:"title", etc.) map the JSON keys to Go struct fields.

Step 2: Fetching JSON Data from an API

func fetchTodos(url string) ([]byte, error) {
    response, err := http.Get(url)
    if err != nil {
        return nil, fmt.Errorf("request to %s failed: %w", url, err)
    }
    defer response.Body.Close()

    if response.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("request failed with status: %s", response.Status)
    }

    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
        return nil, fmt.Errorf("failed to read response body: %w", err)
    }
    return body, nil
}

This function fetches JSON data from the given API URL and returns the raw JSON response body.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal