Reputation: 33587
I'm making a JSON request to a 3rd party API. If my auth token has expired, I receive an {"error": "message"}
. If everything checks out, I receive a valid response.
Right now, I call json.Unmarshal
twice to parse the response: once to check for the error and once to parse the real data.
Is there any way to avoid calling Unmarshal twice?
type Unknown map[string]interface{}
type Response struct {
Status string `json:"status"`
Strategy string `json:"strategy"`
Items []Item `json:"items"`
}
unknown := Unknown{}
json.Unmarshal(jsonData, &unknown)
if val, ok := unknown["error"]; ok {
fmt.Println(val)
return
}
response := Response{}
err := json.Unmarshal(jsonData, &response)
if err != nil {
fmt.Println("There was an error")
fmt.Println(err)
return
}
Upvotes: 0
Views: 2347
Reputation: 38303
You can use embedding to decode everything at once:
type Response struct {
Status string `json:"status"`
Strategy string `json:"strategy"`
Items []Item `json:"items"`
}
var dest struct {
Error string `json:"error"`
Response // embedded Response
}
if err := json.Unmarshal(jsonData, &dest); err != nil {
fmt.Println(err)
return
} else if len(dest.Error) > 0 {
fmt.Println(dest.Error)
return
}
response := dest.Response
// ...
See an example on playground: https://play.golang.com/p/eAhFt99n07k
Upvotes: 3