提问人:osflw 提问时间:8/25/2023 最后编辑:osflw 更新时间:8/28/2023 访问量:228
Golang 识别并验证设置为 null 或未提供的 json 值
Golang identify and validate json value set to null or not provided
问:
我有接受 PATCH 方法并更新给定字段的 API。 具有以下正文的 PATCH 请求会更改用户的年龄。
{
"age": 10
}
我在处理价值方面遇到了问题。
我的结构如下:null
User
type User struct {
Name string
Age int
Schedule *schedule
}
type Schedule struct {
time int
weekdays []int
}
若要删除用户的计划字段,请求正文应如下所示:
{
"schedule": null
}
然后,我必须确定是否提供了 null 值,这在上述定义中是不可能的。 我编写了有助于识别它的新结构(https://www.calhoun.io/how-to-determine-if-a-json-key-has-been-set-to-null-or-not-provided/):
type User struct {
Name
Age int
Schedule Optional[Schedule]
}
type Optional[T any] struct {
Value *T
Defined bool
}
func (t *Optional[T]) UnmarshalJSON(data []byte) error {
t.Defined = true
return json.Unmarshal(data, &t.Value)
}
func (t *Optional[T]) IsNullDefined() bool {
return t.Defined && t.Value == nil
}
func (t *Optional[T]) HasValue() bool {
return t.Defined && t.Value != nil
}
而且,现在我有一个问题,即行动是不同的
{
"age": null
}
这将被忽略,并且
{
"schedule": null
}
这将删除计划。
我该如何处理和防止其他类型的值,这应该是类型错误?null
编辑:
用一句话来说,我想拒绝除可选结构之外的所有给定值字段(不是未提供的字段)。您可以向我建议任何其他解决问题的解决方案。null
答:
0赞
Saurabh Prakash
8/25/2023
#1
尝试将 Age
设为 *int
类型。
尝试创建 an 类型。https://go.dev/play/p/f56pdESOEt7Age
Optional[int]
评论
0赞
osflw
8/25/2023
它不能解决问题。 也忽略 .即,给出“无法识别”字段。*int
"age": null
age
0赞
Saurabh Prakash
8/25/2023
@osflw 检查更新的答案。
0赞
osflw
8/25/2023
谢谢。它解决了这个问题,但我想要的是通用解决方案,即在语言方面进行类型验证。有了解决方案,如果我想拒绝,我必须把我所有的字段和代码都检查有效。我认为这不是一个好主意。null
Optional
0赞
Saurabh Prakash
8/25/2023
@osflw你到底需要做什么?您需要识别以下所有 3 种情况,对吧?1. 有效 2.空 3. 未提供。使用指针,您将只能获得 3 个选项中的 2 个。没有自定义结构是不可能的age
age
age
0赞
osflw
8/25/2023
是的,但默认情况下,它拒绝所有给定的值。因此,只有字段可以接受和删除该字段。null
Optional
null
-1赞
osflw
8/28/2023
#2
从@Volker找到解决方案并发布自我回答:
上述问题使用 Merge Patch JSON (rfc7396)。它有一个图书馆。
https://pkg.go.dev/github.com/evanphx/json-patch/v5#MergePatch
我拉取 GET 结果并合并 GET 结果和 json 补丁体。然后,您可以注意到哪些值被取消了。
评论
Optional[T]
data
UnmarshalJSON
null
if string(data) == "null" {
true
UnmarshalJSON
Required[T]
Required
Optional
"age": null
age
json。Unmarshal
:“JSON null 值通过将 Go 值设置为 nil 来解组到接口、映射、指针或切片中。由于 null 在 JSON 中通常用于表示“不存在”,因此将 JSON null 解组为任何其他 Go 类型对值没有影响,也不会产生错误。encoding/json