0

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)
4

1 回答 1

2

ProductRes您可以使用匿名类型消除声明的类型:

var wrapper struct { Items []Product }
err := json.Unmarshal(body, &wrapper)
if err != nil { 
   // TODO: handle error
}

products := wrapper.Items

您还可以使用地图:

var m map[string][]Product
err := json.Unmarshal(body, &m)
if err != nil { 
   // TODO: handle error
}
products := m["items"]
于 2021-10-29T02:59:27.637 回答