如何在 golang 中处理未设置值的补丁请求
How to handle patch request with unset value in golang
我正在开发补丁 restful 请求正文 json 在发送到 golang 时包含一些省略的值。由于未设置的值将导致 golang 结构成为默认值。所以我想知道有没有解决补丁请求遗漏数据的方法?
据我所知,像 string / int 这样的基本类型在 golang 中不能为空。有不同的方法来处理未设置的值补丁请求。例如:
使用指针处理null问题
type User struct {
Name *string
}
使用可空库
type User struct {
Name sql.NullString
}
使用map[string][]interface{}
查看值是否设置
有没有更好的解决方案来处理结构中的可为空值?因为这 3 应该解决来处理可为 null 的值。
将指针与 omitempty
标记一起使用。这样您就可以区分未设置的值 nil 和故意的零值 ("", false, 0)。
type User struct {
Name *string `json:"name,omitempty"`
}
另一个解决方案是编写自己的类型,并实现 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 以了解从结构到 json 的反向结构。
如果您以 RESTful 的方式使用 PATCH
,这意味着它正在更新一些现有数据,并且只会覆盖请求正文中包含的那些字段。这意味着您实际上不需要知道哪些字段已设置或未设置;您可以只加载您的规范对象并对其进行解组以替换 JSON 中找到的任何字段,同时保持其他任何字段不变:
canonObj := getObjectFromDBOrSomething()
err := json.NewDecoder(req.Body).Decode(canonObj)
这将使用请求中的字段覆盖 canonObj
中的任何字段,但不会触及请求中 而非 中的任何字段。
我正在开发补丁 restful 请求正文 json 在发送到 golang 时包含一些省略的值。由于未设置的值将导致 golang 结构成为默认值。所以我想知道有没有解决补丁请求遗漏数据的方法?
据我所知,像 string / int 这样的基本类型在 golang 中不能为空。有不同的方法来处理未设置的值补丁请求。例如:
使用指针处理null问题
type User struct { Name *string }
使用可空库
type User struct { Name sql.NullString }
使用
map[string][]interface{}
查看值是否设置
有没有更好的解决方案来处理结构中的可为空值?因为这 3 应该解决来处理可为 null 的值。
将指针与 omitempty
标记一起使用。这样您就可以区分未设置的值 nil 和故意的零值 ("", false, 0)。
type User struct {
Name *string `json:"name,omitempty"`
}
另一个解决方案是编写自己的类型,并实现 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 以了解从结构到 json 的反向结构。
如果您以 RESTful 的方式使用 PATCH
,这意味着它正在更新一些现有数据,并且只会覆盖请求正文中包含的那些字段。这意味着您实际上不需要知道哪些字段已设置或未设置;您可以只加载您的规范对象并对其进行解组以替换 JSON 中找到的任何字段,同时保持其他任何字段不变:
canonObj := getObjectFromDBOrSomething()
err := json.NewDecoder(req.Body).Decode(canonObj)
这将使用请求中的字段覆盖 canonObj
中的任何字段,但不会触及请求中 而非 中的任何字段。