我们正在使用Golang来实现包括CRUD在内的REST API,在Update服务中,客户端可以发送包括已更改字段的部分JSON,因此我们需要处理通过这些更改来更新实体。
从逻辑上讲,我们需要通过ID从数据库获取实体到结构,然后将有效载荷json解组到另一个结构并更新实体。
但是如果有效负载json不完整,例如我有struct
type Customer struct {
Id int64 `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
JSON请求看起来像
{
"Name": "Updated name"
}
然后应使用新名称更新客户。
这是一个简单的示例,实际上它可能是一个嵌套的结构和一个嵌套的json,我们如何用golang或事件其他语言(如Java,.NET)处理这种情况
答案 0 :(得分:2)
如果Update请求使用相同的Customer
结构,则结构字段可以是用于区分零值和未在JSON中设置的值的指针。
现在,您需要做的就是将现有结构合并到更新的Consumer
结构中。
为此,您可以在Go中使用https://github.com/imdario/mergo库。
package main
import (
"fmt"
"github.com/imdario/mergo"
"encoding/json"
"os"
)
type Address struct {
City string `json:"city"`
}
type Customer struct {
Id int64 `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
Address *Address `json:"address"`
}
func main() {
old1 := &Customer{Id:1, Name:"alpha", Age:5, Address:&Address{City:"Delhi"}}
b := []byte(`{"name": "beta"}`) //no address, age specified picks from old
up1 := new(Customer)
json.Unmarshal(b, up1)
if err := mergo.Merge(up1, old1); err != nil {
fmt.Printf("err in 1st merge: %v\n", err)
os.Exit(1)
}
m1, _ := json.Marshal(up1)
fmt.Printf("merged to: %v\n", string(m1))
old2 := &Customer{Id:1, Name:"alpha", Age:5, Address:&Address{City:"Delhi"}}
b2 := []byte(`{ "address": {"city": "mumbai"}}`) //address specified
up2 := new(Customer)
json.Unmarshal(b2, up2)
if err := mergo.Merge(up2, old2); err != nil {
fmt.Printf("err in 1st merge: %v\n", err)
os.Exit(1)
}
m2, _ := json.Marshal(up2)
fmt.Printf("merged to: %v\n", string(m2))
}
答案 1 :(得分:0)
从您的评论中看来,您遇到了许多go
用户,即零值问题,即如何判断输入数据是否传递了合法值-或该值默认为零。
解决此问题的唯一方法是使用指针。因此,在您的示例中,将数据结构更改为此:
type Customer struct {
Id *int64 `json:"id"`
Name *string `json:"name"`
Age *int `json:"age"`
}
然后在取消编组后,所有未初始化的字段都将具有nil
值,例如
var c Customer
err := json.Unmarshal(jsonData, &c)
if err != nil {
panic(err)
}
if c.Id != nil {
log.Println("TODO: added SQL update parms for c.Id:", *c.Id)
}
if c.Name != nil {
log.Println("TODO: added SQL update params for c.Name:", *c.Name)
}
if c.Age != nil {
log.Println("TODO: added SQL update parms for c.Age:", *c.Age)
}
注意:必须注意确保不会意外引用任何会触发即时panic
的nil指针。