Go语言 在密钥不存在时处理PATCH部分更新

nnsrf1az  于 2023-03-10  发布在  Go
关注(0)|答案(1)|浏览(169)

我在想怎么解决这个问题。
我有一个User结构体,它上面有几个字段。但是,当为PATCH用户调用解码JSON对象时,缺少键会导致值被设置为 *nil。相应的数据库属性是TEXT NULL类型,因此当缺少键时,结果将始终存储为NULL。

type UpdateUserDTO struct {
  ID         uuid.UUID
  FirstName  string
  LastName   string
  ImageURL  *string
}

ImageURL可以为nil,但是当从客户端发送此对象时:

{ firstName: "Jimmy" }

这将解码为ImageURL = nil,因为JSON中不存在imageUrl
如何处理部分更新,而不使用map[string]struct{}而不是DTO检查每个字段是否存在?

afdcj2ne

afdcj2ne1#

您可以实现一个自定义json.Unmarshaler来确定该字段是完全省略、提供了但其值为null,还是提供了非空值。

type OptString struct {
    IsValid bool
    String  *string
}

// If a field with this type has no corresponding field in the
// incoming JSON then this method will not be invoked and the
// IsValid flag's value will remain `false`.
func (s *OptString) UnmarshalJSON(data []byte) error {
    if err := json.Unmarshal(data, &s.String); err != nil {
        return err
    }
    s.IsValid = true
    return nil
}
type UpdateUserDTO struct {
    ID        uuid.UUID
    FirstName string
    LastName  string
    ImageURL  OptString
}

https://go.dev/play/p/hvS5E46sgkD
另一种不需要自定义类型的方法是,将Go字段的值设置为 current 数据库列的值,然后JSON进行反编组,如果传入的JSON不包含匹配字段,则json.Decoder(由json.Unmarshal使用)不会“接触”目标的字段。

dto := loadUpdateUserDTOFromDB(conn)
if err := json.Unmarshal(data, dto); err != nil {
    return err
}

https://go.dev/play/p/grJhr4P7sgQ

相关问题