Search code examples
arraysjsongounmarshalling

string is nil when unmarshaling json in Golang


I'm trying to unmarshal a json in Golang, which looks like this:

{"graph":[[1650970800,1859857],[1650972600,1918183]...],"records":246544,"period":"24h","zone":"test.com","queries":93321} 

While I can unmarshal some of the values, others are simply empty i.e zone or graph (but those values are returned in the Json). Here's my code

type NSoneResponse struct {
Graphs  []Graph
Records int64
Period  string
Zones   string
Queries int64
}

type Graph struct {
    Timestamp int64
    Queries   int64
}

const (
    zoneUsageUrl  = "https://api.nsone.net/v1/stats/usage/test.com?period=24h&networks=*"
)

func main() {
    getUsageData(zoneUsageUrl)
}

func getUsageData(url string) {
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        log.Fatal(err)
    }

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    var filteredData []NSoneResponse
    err = json.Unmarshal([]byte(body), &filteredData)
    if err != nil {
        panic(err)
    }

    for i := range filteredData {
        fmt.Printf("Quieries per timestamp: %v\nRecords count: %v\nPeriod: %v\nZone: %v\nNumber of queries: %v\n", filteredData[i].Graphs, filteredData[i].Records, filteredData[i].Period, filteredData[i].Zones, filteredData[i].Queries)

    }
}

The output at the end

Quieries per timestamp: []
Record count: 243066
Period: 24h
Zone:
Number of queries: 91612963

When I tried to use pointers in the NSoneResponse struct, I got nil for those values instead (note - the Period key also contains string value, yet it does not return nil)

Quieries per timestamp: <nil>
Quota count: 0xc000274470
Period: 0xc000460310
Zone: <nil>
Number of queries: 0xc000274488  

What am I doing wrong?


Solution

  • first of all, I will explain the mistake in your code, you should use struct tags. because your Graphs variable of your struct is not equal of graph in your json, this mistake is on zone variable too. change your struct to this :

    type NSoneResponse struct {
        Graphs  [][]int `json:"graph"`
        Records int64   `json:"records"`
        Period  string  `json:"period"`
        Zones   string  `json:"zone"`
        Queries int64   `json:"queries"`
    }
    

    also, your JSON has an array of int not an array of Objects, so you must change the type of Graphs. after that, you should convert the array of int to an array of graphs.