jsongogo-http

Go json manipulation


Hey there just started to transform my python code to Go, but have some issue on the json manipulations... here is my code so far

package test

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "strings"
    "time"
)

type Collection struct {
    Contract string
}

type Data struct {
    Activity Activity `json:"activity"`
}

type Activity struct {
    Activities Activities `json:"activities"`
    HasMore    bool       `json:"hasMore"`
}

type Activities []Sale

type Sale struct {
    From             string           `json:"from"`
    From_login       string           `json:"from_login"`
    To               string           `json:"to"`
    To_login         string           `json:"to_login"`
    Transaction_hash string           `json:"transaction_hash"`
    Timestamp        int              `json:"timestamp"`
    Types            string           `json:"type"`
    Price            float32          `json:"price"`
    Quantity         string           `json:"quantity"`
    Nft              Nft              `json:"nft"`
    Attributes       string           `json:"attributes"`
    Collection       CollectionStruct `json:"collection"`
}

type Nft struct {
    Name       string        `json:"name"`
    Thumbnail  string        `json:"thumbnail"`
    Asset_id   string        `json:"asset_id"`
    Collection NftCollection `json:"collection"`
}

type NftCollection struct {
    Avatar    string `json:"avatar"`
    Name      string `json:"name"`
    Certified bool   `json:"certified"`
}

type CollectionStruct struct {
    Avatar    string `json:"avatar"`
    Address   string `json:"address"`
    Name      string `json:"name"`
    Certified bool   `json:"certified"`
}

func (c Collection) GetSales(filter, types string) []Sale { // déclaration de ma méthode GetSales() liée à ma structure Collection
    client := &http.Client{Timeout: time.Duration(1) * time.Second}

    const url = "https://backend.api.io/query"

    // create a new request using http
    req, err := http.NewRequest("POST", url)
    if err != nil {
        panic(err)
    }

    // set header for the request
    req.Header.Set("Content-Type", "application/json")

    // send request
    res, err := client.Do(req)
    if err != nil {
        panic(err)
    }

    defer res.Body.Close()
    content, err_ := ioutil.ReadAll(res.Body)
    if err_ != nil {
        panic(err_)
    }

    var resultJson Data
    json.Unmarshal(content, &resultJson)
    fmt.Printf("%+v\n", resultJson)
    return resultJson.Activity.Activities.Sale

}

i don't understand why my Sale structure is empty :/ I created all of these structures in order to use Unmarshal so i can loop. I check the way the returned json is structured and copied it i'm sure i missed something but don't know what

EDIT: I think that i have something, actually the array is Activities and not Sale :

type Collection struct {
    Contract string
}

type Data struct {
    Activity Activity `json:"activity"`
}

type Activity struct {
    Activities Activities `json:"activities"`
    HasMore    bool       `json:"hasMore"`
}

type Activities []struct {
    Sale Sale //`json:"sale"`
}

type Sale struct {
    From             string           `json:"from"`
    From_login       string           `json:"from_login"`
    To               string           `json:"to"`
    To_login         string           `json:"to_login"`
    Transaction_hash string           `json:"transaction_hash"`
    Timestamp        int              `json:"timestamp"`
    Types            string           `json:"type"`
    Price            float32          `json:"price"`
    Quantity         string           `json:"quantity"`
    Nft              Nft              `json:"nft"`
    Attributes       string           `json:"attributes"`
    Collection       CollectionStruct `json:"collection"`
}

type Nft struct {
    Name       string        `json:"name"`
    Thumbnail  string        `json:"thumbnail"`
    Asset_id   string        `json:"asset_id"`
    Collection NftCollection `json:"collection"`
}

type NftCollection struct {
    Avatar    string `json:"avatar"`
    Name      string `json:"name"`
    Certified bool   `json:"certified"`
}

type CollectionStruct struct {
    Avatar    string `json:"avatar"`
    Address   string `json:"address"`
    Name      string `json:"name"`
    Certified bool   `json:"certified"`
}

But this time it returns me this : {Activity:{Activities:[] HasMore:false}} where Activities value should be an array of Nft struct


Solution

  • Adding to @larsks 's answer, there are more errors that I can see

    1. ioutil.ReadAll already returns a byte array which you can directly use for un-marshalling. json.Unmarshal(content, &resultJson)

    2. Many errors are ignored so execution won't stop if any error is encountered.

    I suggest changing the function as follows:

    func (c Collection) GetSales(filter, types string) []Sale {
        const url = "https://api.com/"
    
        req, err := http.NewRequest("POST", url, requestBody)
        if err != nil {
            panic(err)
        }
        
        res, err := http.DefaultClient.Do(req)
        if err != nil {
            panic(err)
        }
    
        defer res.Body.Close()
        content, err := ioutil.ReadAll(res.Body)
        if err != nil {
            panic(err)
        }
    
        var resultJson Data
        err = json.Unmarshal(content, &resultJson)
        if err != nil {
            panic(err)
        }
    
        fmt.Printf("%+v\n", resultJson)
        return resultJson.Activity.Activities.Sales
    }