为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
阿波罗的战车 2022-08-30 15:19:05
使用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 $bodyPS C:\Git> $response[0] | gm   TypeName: System.Management.Automation.PSCustomObjectName         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=21731777isBestMatch  NoteProperty bool isBestMatch=TrueisBuyerMaker NoteProperty bool isBuyerMaker=Trueprice        NoteProperty string price=3539.03000000qty          NoteProperty string qty=0.28600000quoteQty     NoteProperty string quoteQty=1012.16258000time         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{}我感到非常卡住,就像我错过了与编组有关的东西一样,有人可以帮助我吗?
查看完整描述

3 回答

?
冉冉说

TA贡献1877条经验 获得超1个赞

由于 JSON 响应是一个数组,因此需要将其取消编组为结构切片。确保还使用正确的 Go 类型。用于 JSON 编号。float64


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

}


查看完整回答
反对 回复 2022-08-30
?
慕斯709654

TA贡献1840条经验 获得超5个赞

如果我们有一个json样本(模拟),以了解由于json是否存在确切的问题,可能会有所帮助。

我怀疑,因为你有一个你之前提到的结构的ARRAY,你应该在a上做一个unmarshal,而不是一个Final for json类型,有一种规则集,当你做一个unmarshal时,但只有当你的字段ar类型:[]Trade{}Trade{}interface{}

//img1.sycdn.imooc.com//630dba1300018e6a07280180.jpg

查看完整回答
反对 回复 2022-08-30
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

如果你正在获取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

  }

]

在代码中,需要执行这些操作。

  1. 声明一个交易结构的切片,

  2. 执行此数据到该切片的 json 解编组

  3. 循环访问切片以获取每个 json 对象上的处理程序。

  4. 现在,您可以形成一个 sql 查询并访问每个 json 对象的 json 值,并对数据库进行查询。

像这样的东西。

// Assuming r is your default http.Request handler, get the complete request body

byteSlice, err := ioutil.ReadAll(r.Body)

    if err != nil {

        log.Println("Error in reading request body")

    }


var trades []Trade


if 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.

}


查看完整回答
反对 回复 2022-08-30
  • 3 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信