将 JSON 数组 API 响应转换为结构

使用Go,我希望查询API端点并将结果输出到Gorm SQLite数据库。这之前(这里)已经完成,但我需要自己编写代码。


API端点返回一个JSON数组,对于数组中的每个交易,我想将其放入一个结构中,然后将其作为行添加到SQLite数据库中。


结构定义如下:


type Trade struct {

    TradeID      int64  `json:"id"`

    Price        string `json:"price"`

    Qty          string `json:"qty"`

    QuoteQty     string `json:"quoteQty"`

    Time         int64  `json:"time"`

    IsBuyerMaker bool   `json:"isBuyerMaker"`

    IsBestMatch  bool   `json:"isBestMatch"`

}

这些类型可能看起来很奇怪,但是通过使用以下代码的PowerShell来确定的:


PS C:\Git> $body = @{"symbol" = "ETHEUR";"limit" = 1000}

PS C:\Git> $response = Invoke-RestMethod https://api.binance.com/api/v3/trades -Body $body

PS C:\Git> $response[0] | gm


   TypeName: System.Management.Automation.PSCustomObject


Name         MemberType   Definition

----         ----------   ----------

Equals       Method       bool Equals(System.Object obj)

GetHashCode  Method       int GetHashCode()

GetType      Method       type GetType()

ToString     Method       string ToString()

id           NoteProperty long id=21731777

isBestMatch  NoteProperty bool isBestMatch=True

isBuyerMaker NoteProperty bool isBuyerMaker=True

price        NoteProperty string price=3539.03000000

qty          NoteProperty string qty=0.28600000

quoteQty     NoteProperty string quoteQty=1012.16258000

time         NoteProperty long time=1620822731248

因此,到目前为止,我拥有的Go函数如下:



func getTrade(symbol string, limit int) {

    uri := fmt.Sprintf("https://api.binance.com/api/v3/trades?symbol=%v&limit=%v", symbol, limit)


    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})

    if err != nil {

        panic("failed to connect database")

    }


    // Create the fields in the database based on the Trade Struct

    db.AutoMigrate(&Trade{})


    // Query Binance API endpoint

    response, err := http.Get(uri)


    // Log if an error occurred

    if err != nil {

        log.Fatalln(err)

    }


    // Defer closing object

    defer response.Body.Close()


    // Create trade struct

    trade := Trade{}


我感到非常卡住,就像我错过了与编组有关的东西一样,有人可以帮助我吗?


阿波罗的战车
浏览 127回答 3
3回答

冉冉说

由于 JSON 响应是一个数组,因此需要将其取消编组为结构切片。确保还使用正确的 Go 类型。用于 JSON 编号。float64type Trade struct {    TradeID      float64 `json:"id"`    Price        string  `json:"price"`    Qty          string  `json:"qty"`    QuoteQty     string  `json:"quoteQty"`    Time         float64 `json:"time"`    IsBuyerMaker bool    `json:"isBuyerMaker"`    IsBestMatch  bool    `json:"isBestMatch"`}func main() {    symbol := "ETHEUR"    limit := 1000    uri := fmt.Sprintf("https://api.binance.com/api/v3/trades?symbol=%v&limit=%v", symbol, limit)    response, err := http.Get(uri)    if err != nil {        fmt.Println(err)    }    body, err := ioutil.ReadAll(response.Body)    if err != nil {        fmt.Println(err)    }    defer response.Body.Close()    trade := []Trade{}    err = json.Unmarshal([]byte(body), &trade)    if err != nil {        fmt.Println(err)    }    fmt.Println(trade)}

慕斯709654

如果我们有一个json样本(模拟),以了解由于json是否存在确切的问题,可能会有所帮助。我怀疑,因为你有一个你之前提到的结构的ARRAY,你应该在a上做一个unmarshal,而不是一个Final for json类型,有一种规则集,当你做一个unmarshal时,但只有当你的字段ar类型:[]Trade{}Trade{}interface{}

肥皂起泡泡

如果你正在获取json数组,我假设它们是json对象的数组,每个对象都包含你定义的结构的json。如下面的示例所示。[  {    "id": 1,    "price": "111",    "qty": "20",    "quoteQty": "100",    "time": 6039484,    "isBuyerMaker": true,    "isBestMatch": false  },  {    "id": 2,    "price": "222",    "qty": "20",    "quoteQty": "100",    "time": 6039484,    "isBuyerMaker": true,    "isBestMatch": false  },  {    "id": 3,    "price": "333",    "qty": "20",    "quoteQty": "100",    "time": 6039484,    "isBuyerMaker": true,    "isBestMatch": false  }]如果你正在获取json数组,我假设它们是json对象的数组,每个对象都包含你定义的结构的json。如下面的示例所示。[  {    "id": 1,    "price": "111",    "qty": "20",    "quoteQty": "100",    "time": 6039484,    "isBuyerMaker": true,    "isBestMatch": false  },  {    "id": 2,    "price": "222",    "qty": "20",    "quoteQty": "100",    "time": 6039484,    "isBuyerMaker": true,    "isBestMatch": false  },  {    "id": 3,    "price": "333",    "qty": "20",    "quoteQty": "100",    "time": 6039484,    "isBuyerMaker": true,    "isBestMatch": false  }]在代码中,需要执行这些操作。声明一个交易结构的切片,执行此数据到该切片的 json 解编组循环访问切片以获取每个 json 对象上的处理程序。现在,您可以形成一个 sql 查询并访问每个 json 对象的 json 值,并对数据库进行查询。像这样的东西。// Assuming r is your default http.Request handler, get the complete request bodybyteSlice, err := ioutil.ReadAll(r.Body)    if err != nil {        log.Println("Error in reading request body")    }var trades []Tradeif err = json.Unmarshal(byteSlice, &trades); err != nil {        log.Println("Error in json unmarshal")        http.Error(w, err.Error(), http.StatusBadRequest)        return    }for _, trade := range trades {        log.Println("Trade ID: ", trade.TradeID)        // Call a function and pass each trade object        err := triggerSQLQuery(trade)        if err != nil {          log.Println(err.Error())        }    }func triggerSQLQuery(trade Trade) error {  // Access trade object and form an sql query and execute it.}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go