gojmapr 我的第一個開源項目
gojmapr
- 在README中放入blog連結
Hi 各位,我做了一個Golang開源項目! → gojmapr
介紹
- GO JSON MAPPER 簡稱
gojmapr
。 - 這是一個可以從一坨JSON中只取一些值並Map到的套件。
你有遇到第三方傳來的JSON很復雜,但是你只需要其中幾個屬性而不得不宣告一個超大還層層嵌套的結構嗎?
你在讀取外部JSON的資料時必需要account.user.cart.order...
?
這就是你要找的套件了!:)
套件的誕生
起初我是在寫後端API,我在接從前端來的呼叫時發現我花了很長的時間寫好對應的struct,每次使用時候還必需寫超級長,就產生了為什麼不能用簡單的struct直接讀取我要的值就好了,這樣不僅不用寫一大堆struct嵌套,也不怕之後維護的人把整個struct傳來傳去很難維護。
用法
先來一個復雜的JSON結構
jsonString :=`{
"cart": {
"items": [
{
"product": {
"id": "123",
"name": "Product A",
"description": "Product A description",
"price": 10.99
},
"quantity": 2
},
{
"product": {
"id": "456",
"name": "Product B",
"description": "Product B description",
"price": 5.99
},
"quantity": 1
}
],
"total": 27.97
}
}`
現在我只關心 cart.total 與 cart.items[0].product.id 這兩個值,所以我可以這樣做:
// use gojmpar
type tmpStruct struct {
Total float64 `gojmapr:"$.cart.total"`
ID string `gojmapr:"$.cart.items[0].product.id"`
}
var s tmpStruct
err := Unmarshal([]byte(jsonString), &s)
if err != nil {
panic(err)
}
s := tmpStruct{}
// Total
fmt.Println(s.Total) // 27.97
// ID
fmt.Println(s.ID) // 123
如此一來這兩個值就會map到我的tmpStruct中的Total與ID了。
對比看看原來的做法↓
// origin
type product struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Price float64 `json:"price"`
}
type item struct {
Product product `json:"product"`
Quantity int `json:"quantity"`
}
type cart struct {
Items []item `json:"items"`
Total float64 `json:"total"`
}
type tmpStruct struct {
Cart cart `json:"cart"`
}
s := tmpStruct{}
err := json.Unmarshal([]byte(jsonString), &s)
if err != nil {
panic(err)
}
// Total
fmt.Println(s.Cart.Total) // 27.97
// ID
fmt.Println(s.Cart.Items[0].Product.ID) // 123
就可以發現在越復雜的JSON格式中,這個套件越有優勢。
關於gojmapr的Umarshal效率
- 因為算法用了反射,所以效率會比直接取值還慢一點點,在一般的API場景下使用沒有問題,若是用在高併發的情況下則最好先做benchmark。
- 由於很官方的JSON套件效率原因,因此這裡也提供使用其他套件來取代官方套件的方法,以下是使用github.com/json-iterator/go
// use 3rd plugin to decode json
import jsoniter "github.com/json-iterator/go"
type tmpStruct struct {
RequestID string `gojmapr:"$.request_id"`
}
SetUnmarshalFunc(jsoniter.Unmarshal) // You can use other Unmarshal module ex: json-iterator
var s tmpStruct
err := Unmarshal([]byte(jsonString), &s)
ex.Assert().Nil(err)
ex.Assert().Equal(ex.anserStruct.RequestID, s.RequestID)
最後
如果覺的不錯就給我Github的星星吧 XD,我真的很想要呢!
-> gojmapr
留言
張貼留言