【发布时间】:2021-08-02 20:01:11
【问题描述】:
使用 Go,我希望查询 API 端点并将结果输出到 Gorm SQLite DB。这在(here)之前已经完成了,但是我需要自己写代码。
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{}
从这里我尝试了几种将响应转换为结构的方法,但都失败了。这些方法包括:
// Unmarshal bytes to data struct
_ = json.Unmarshal([]byte(responseData), &trade)
var myClient = &http.Client{Timeout: 10 * time.Second}
func getJson(url string, target interface{}) error {
response, err := myClient.Get(url)
if err != nil {
return err
}
defer response.Body.Close()
return json.NewDecoder(response.Body).Decode(target)
}
// Iterate through trades returned (this doesn't work)
for _, trade := range responseData {
tradeVariable := Trade{}
tradeVariable.TradeID = trade.id
fmt.Println(tradeVariable.TradeID)
}
我感觉真的被困住了,好像我错过了与编组有关的东西,有人可以帮我吗?
【问题讨论】:
-
对于包含对象的 json 数组,您应该使用 Go 结构切片,而不是 只是 结构。即
trades := []Trade{}并将&trades传递给json.Unmarshal并确保不要丢弃_的错误,而是正确检查并处理它。如果结构体的字段类型有问题,json.Unmarshal返回的错误会非常清楚地告诉您。