我正在嘗試解組 HTTP REST API 請求的結果,該請求取決于結果的數量,回傳一個物件或一個物件陣列。
請求是通用的,因為我試圖圍繞特定的 REST API 構建一個包裝器,它被稱為:
// Function prototype where I am trying to convert the response
func (client *Client) Get(endpoint string, data map[string]string) (map[string]json.RawMessage, error)
// The way the function is called
client.Get("/v1/users", map[string]string{"filter.abc": "lorem ipsum"})
兩個回應示例:
[
{
"abc": "def",
"efg": 123
"hij": [
{
"klm": "nop"
}
]
},
{
"abc": "def",
"efg": 123
"hij": [
{
"klm": "nop"
}
]
}
]
// RESPONSE 1: Array of JSON objects that have child arrays
{
"abc": "def",
"efg": 123
"hij": [
{
"klm": "nop"
}
]
}
// RESPONSE 2: In this case, only one element was returned.
我已經實作了僅針對回應 2 執行此操作,如下所示:
// [...]
byteBody = ioutil.ReadAll(res.Body)
// [...]
var body map[string]json.RawMessage
if err := json.Unmarshal(byteBody, &body); err != nil { [...] }
那么,決議這個最慣用的方法是什么?有什么方法可以避免撰寫冗余代碼并決議兩個回應?我正在考慮將回應應該放入的“模型”作為附加引數。這是一個好習慣嗎?非常感謝您!
uj5u.com熱心網友回復:
檢查 JSON 檔案中的第一個非空白位元組以確定該檔案是陣列還是物件。
func decodeArrayOrObject(doc []byte) ([]map[string]json.RawMessage, error) {
trimmedDoc := bytes.TrimSpace(doc)
switch {
case len(trimmedDoc) == 0:
return nil, errors.New("empty body")
case trimmedDoc[0] == '{':
var m map[string]json.RawMessage
err := json.Unmarshal(doc, &m)
return []map[string]json.RawMessage{m}, err
case trimmedDoc[0] == '[':
var s []map[string]json.RawMessage
err := json.Unmarshal(doc, &s)
return s, err
default:
return nil, errors.New("unexpected type")
}
}
使用反射包創建一個適用于任意切片型別的函式:
func decodeArrayOrObject(doc []byte, slicep interface{}) error {
trimmedDoc := bytes.TrimSpace(doc)
switch {
case len(trimmedDoc) == 0:
return errors.New("empty document")
case trimmedDoc[0] == '[':
return json.Unmarshal(doc, slicep)
case trimmedDoc[0] == '{':
s := reflect.ValueOf(slicep).Elem()
s.Set(reflect.MakeSlice(s.Type(), 1, 1))
return json.Unmarshal(doc, s.Index(0).Addr().Interface())
default:
return errors.New("unexpected type")
}
}
使用指向結構切片的指標或指向結構指標切片的指標呼叫函式。
var v []Example
err := decodeArrayOrObject(body, &v)
在操場上運行一個示例。
uj5u.com熱心網友回復:
不確定是慣用的,但此代碼可能是一個示例。
簡而言之,您可以嘗試以一種格式解組,如果失敗,則使用另一種格式
關鍵功能是
func parseStr(data string) ([]Item, error) {
item := Item{}
if err := json.Unmarshal([]byte(data), &item); err == nil {
return []Item{item}, nil
}
items := []Item{}
if err := json.Unmarshal([]byte(data), &items); err != nil {
return nil, errors.New("invalid JSON data")
}
return items, nil
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/488419.html
上一篇:在Python中使用aiohttp上傳Google驅動器檔案
下一篇:使用令牌的角度訪問
