简体   繁体   中英

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

Your code as written won't compile (due to a couple of undefined variables), so it's hard to separate functional problems from syntactic problems.

However, one thing stands out: You're creating an HTTP request with req, err:= http.NewRequest(...) , but you're never executing the request with a client. See eg the documentation , which includes this example:

client := &http.Client{
    CheckRedirect: redirectPolicyFunc,
}

resp, err := client.Get("http://example.com")
// ...

req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...

If you use NewRequest to create a request, you must use client.Do(req) to execute it.

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM