代码之家  ›  专栏  ›  技术社区  ›  Blake Rivell

将复杂的http json响应数组转换为简单的结构片,而无需使用Go创建多个结构来匹配响应

  •  0
  • Blake Rivell  · 技术社区  · 3 年前

    如果http响应的格式不是直接的对象列表,那么我唯一能弄清楚如何将它们转换为结构的方法就是创建两个结构来匹配响应的确切格式。在我只需要创建一个产品结构而不需要创建ProductRes包装结构的情况下,是否还有其他方法可以执行此清理程序?

    下面是我调用的api响应的示例:

    {
        "items": [
            {
                "name": "Product 1",
                "price": 20.45
            },
            {
                "name": "Product 2",
                "price": 31.24
            }
                
        ]
    }
    

    以下是我创建的两个结构,用于将api响应转换为产品的一部分:

    type Product struct {
        Name          string  `json:"name"`
        Price         float64 `json:"price"`
    }
    
    type ProductRes struct {
        Items []Product `json:"items"`
    }
    

    下面是发出api请求并将响应转换为产品片段的部分代码:

    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)
    
    1 回复  |  直到 3 年前
        1
  •  2
  •   Penélope Stevens    3 年前

    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"]
    
    推荐文章