我正在处理补丁恢复请求,即在发送到golang时,正文json包含一些省略的值。由于未设置的值将导致golang结构变为默认值。所以我想知道是否有任何解决方案来处理补丁请求省略数据?
据我所知,像golang这样的基本类型如string / int不能为空。处理未设置的值补丁请求有不同的方法。例如:
使用指针处理null问题
type User struct {
Name *string
}
使用可空库
type User struct {
Name sql.NullString
}
使用map[string][]interface{}
查看值是否已设置
有没有更好的解决方案来处理struct中的可空值?因为这3应该解决可以为空的价值。
答案 0 :(得分:6)
如果您以RESTful方式使用PATCH
,这意味着它会更新一些现有数据,并且只会覆盖请求正文中包含的那些字段。这意味着您实际上并不需要知道哪些字段已设置;你可以加载你的规范对象并在其上解组以替换在JSON中找到的任何字段,同时保持其他任何字段不受影响:
canonObj := getObjectFromDBOrSomething()
err := json.NewDecoder(req.Body).Decode(canonObj)
这将使用请求中的字段覆盖canonObj
中的所有字段,但请求中的任何字段不都不会被触及。
答案 1 :(得分:2)
将指针与omitempty
标记一起使用。通过这种方式,您可以区分未设置的值,nil和有意的零值("",false,0)。
type User struct {
Name *string `json:"name,omitempty"`
}
答案 2 :(得分:0)
另一种解决方案是编写自己的类型,并实现json.Unmarshaller
package main
import (
"encoding/json"
"fmt"
)
type NullString struct {
Data string
Null bool
}
func (ns *NullString) UnmarshalJSON(d []byte) error {
if string(d) == "null" {
// this is based on your need. you may add a new field here
ns.Null = true
return nil
}
return json.Unmarshal(d, &ns.Data)
}
type Test struct {
Data1 NullString `json:"data1"`
Data2 NullString `json:"data2"`
Data3 NullString `json:"data3"`
}
const t = `{"data1":null, "data2":"string"}`
func main() {
p := Test{}
json.Unmarshal([]byte(t), &p)
fmt.Printf("%+v", p)
}
如果值为{Data1:{Data: Null:true} Data2:{Data:string Null:false} Data3:{Data: Null:false}}
,则结果为null
,然后设置Null字段。如果需要,您也可以在此结构中添加额外的字段。例如,跟踪函数是否被调用的字段。
ps:还可以看到json.Marshaller从struct到json的反向。