I'm new to Golang. I'm trying to figure out how to parse a JSON response from an HTTPS request. I've done this before by unmarshalling into a struct, but I couldn't get that working for this JSON, possibly because it starts with an 'unnamed' array? Not sure.
Below is a shortened sample of the JSON. The only part I need are the tokens. I'd like to just print them out.
[
{"queryId":"a5e0cde8-462b-4df2-b275-dca7b89aa903",
"queryType":"Batch",
"description":null,
"tokens":
[
{
"name":"Device",
"type":"STRING",
"isList":true,
"default":"all",
"description":"The device identifier."
},
{
"name":"StartUsageTime",
"type":"TIMESTAMP",
"isList":false,
"default":"1900-1-1",
"description":"Start datetime."
},
{
"name":"EndUsageTime",
"type":"TIMESTAMP",
"isList":false,
"default":"9999-12-31",
"description":"End datetime."
}
]
}
]
My code (below) works. But the part where it's ranging over 'tokens' is ugly and feels clunky to me. Note: I removed all of the error checking for posting here; it is in the actual code.
func getRequest(authToken string) {
reqUrl := fmt.Sprintf("https://host.com?params")
req, err := http.NewRequest(http.MethodGet, reqUrl, nil)
req.Header.Set("Authorization", "Bearer "+authToken)
resp, err := http.DefaultClient.Do(req)
if resp.Body != nil {
defer resp.Body.Close()
}
body, err := io.ReadAll(resp.Body)
var jbody []any
err = json.Unmarshal(body, &jbody)
for _, value := range jbody {
theMap := value.(map[string]any)
tokens := theMap["tokens"].([]any)
for _, v := range tokens {
fmt.Printf(" - Name: %s\n", v.(map[string]any)["name"])
fmt.Printf(" - Type: %s\n", v.(map[string]any)["type"])
fmt.Printf(" - IsList: %t\n", v.(map[string]any)["isList"])
fmt.Printf(" - Default: %s\n", v.(map[string]any)["default"])
fmt.Printf(" - Description: %s\n\n", v.(map[string]any)["description"])
}
}
}
Is there a better way to access those 'tokens'? Or a way to unmarshall this JSON into a struct? I could not figure that out.
You can Define Structs
type Token struct {
Name string `json:"name"`
Type string `json:"type"`
IsList bool `json:"isList"`
Default string `json:"default"`
Description string `json:"description"`
}
type Query struct {
QueryID string `json:"queryId"`
QueryType string `json:"queryType"`
Description *string `json:"description"`
Tokens []Token `json:"tokens"`
}
func getRequest(authToken string) {
reqUrl := fmt.Sprintf("https://host.com?params")
req, err := http.NewRequest(http.MethodGet, reqUrl, nil)
req.Header.Set("Authorization", "Bearer "+authToken)
resp, err := http.DefaultClient.Do(req)
if resp.Body != nil {
defer resp.Body.Close()
}
body, err := io.ReadAll(resp.Body)
var queries []Query
err = json.Unmarshal(body, &queries)
for _, query := range queries {
for _, token := range query.Tokens {
fmt.Printf(" - Name: %s\n", token.Name)
fmt.Printf(" - Type: %s\n", token.Type)
fmt.Printf(" - IsList: %t\n", token.IsList)
fmt.Printf(" - Default: %s\n", token.Default)
fmt.Printf(" - Description: %s\n\n", token.Description)
}
}
}