If an http response comes in a format that is not directly a list of objects the only way I could figure out how to convert them to structs is by creating two structs to match the exact format of the response. Is there anyway to do this cleaner where I can just create a Product struct and don't need to create the ProductRes wrapper struct?
Below is an example of what the response from the api I am calling looks like:
{
"items": [
{
"name": "Product 1",
"price": 20.45
},
{
"name": "Product 2",
"price": 31.24
}
]
}
Here are the two structs I create to convert the api response to a slice of Product:
type Product struct {
Name string `json:"name"`
Price float64 `json:"price"`
}
type ProductRes struct {
Items []Product `json:"items"`
}
Here is part of the code to make the api request and convert the response to a slice of Product:
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
log.Fatalln(err)
}
resp, err := c.client.Do(req)
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
products := ProductRes{}
// This line makes me think I actually do need multiple structs, unless I can modify body somehow prior to sending it in here
json.Unmarshal(body, &products)
CodePudding user response:
You can eliminate the declared type ProductRes
by using an anonymous type:
var wrapper struct { Items []Product }
err := json.Unmarshal(body, &wrapper)
if err != nil {
// TODO: handle error
}
products := wrapper.Items
You can also use a map:
var m map[string][]Product
err := json.Unmarshal(body, &m)
if err != nil {
// TODO: handle error
}
products := m["items"]