JSON to struct omitempty PATCH 与 POST 问题
Posted
技术标签:
【中文标题】JSON to struct omitempty PATCH 与 POST 问题【英文标题】:JSON to struct omitempty PATCH versus POST problem 【发布时间】:2021-12-04 18:09:41 【问题描述】:我正在用 Go 设计一些 REST API 端点。我使用结构来定义在我的 API 方法中处理的对象。这些对象以 json 格式发送并存储在 Firebase 中。假设我有以下简单的结构:
type Person struct
Name string `json:"name" firestore:"name"`
Gender string `json:"gender,omitempty" firestore:"gender"`
Nationality string `json:"nationality,omitempty" firestore:"nationality"`
而且我有以下要求:
在执行GET
请求并从 firebase 读取时,所有字段都是必需的。
在执行 POST
请求并将 json 正文序列化为结构时,所有字段都是必需的。
在执行PATCH
请求并将json 正文序列化为结构时,只需要Name
字段。
对于所有方法,基于相同结构进行序列化的最简洁方法是什么?执行GET
请求时没有问题,因为所有字段都存在并且需要存在于 Firebase 中。但是,当我要使用 omitempty
标记进行 json 序列化时,我无法强制 POST
请求包含所有字段,而 PATCH
请求仅包含字段子集。
【问题讨论】:
为补丁定义不同的模型结构对我来说似乎足够干净。想要重用相同的Person
模型是否有特殊原因?或者你的意思是补丁可能还包含其他字段,但只要求Name
?
我认为“omitempty”标签仅用于将结构编组为 JSON 的情况,这意味着如果您解组一个空的 json 字符串,您将获得具有零值的结构。因此,对于 GET 请求,您将获得从数据库填充的值或默认的零值,并且您将在下游为它们提供服务。这里“omitempty”标签发挥作用:如果它被设置,如果值是零值,生成的json将不包含结构中的键。
【参考方案1】:
我可能会写一个验证函数。
type Person struct
Name string `json:"name" firestore:"name"`
Gender string `json:"gender,omitempty" firestore:"gender"`
Nationality string `json:"nationality,omitempty" firestore:"nationality"`
// ValidatePost validates the struct contains values for all mandatory fields for POST operations
func (p Person) ValidatePost()bool
if p.Name =="" || p.Gender == "" || p.Nationality == ""
return false
return true
// ValidatePatch validates the struct contains values for all mandatory fields for PATCH operations
func (p Person) ValidatePatch()bool
if p.Name ==""
return false
return true
【讨论】:
【参考方案2】:您可以实现custom marshal 接口或使用支持自定义json 标签的https://github.com/json-iterator/go
等第三方库
package main
import (
"fmt"
jsoniter "github.com/json-iterator/go"
)
type Person struct
Name string `json1:"name" json2:"name"`
Gender string `json1:"gender,omitempty" json2:"gender"`
Nationality string `json1:"nationality,omitempty" json2:"nationality"`
func main()
p := PersonName: "bob"
json1 := jsoniter.ConfigTagKey: "json1".Froze()
json2 := jsoniter.ConfigTagKey: "json2".Froze()
b1, _ := json1.Marshal(&p)
b2, _ := json2.Marshal(&p)
fmt.Println(string(b1))
fmt.Println(string(b2))
输出:
"name":"bob"
"name":"bob","gender":"","nationality":""
【讨论】:
谢谢,我认为这是一个干净的解决方案。以上是关于JSON to struct omitempty PATCH 与 POST 问题的主要内容,如果未能解决你的问题,请参考以下文章
Protocol Buffer 去除 json omitempty