如何在发布请求中检查json.body中是否存在空值

时间:2019-12-29 15:24:25

标签: json api go post

我有一个包含4个字段的结构:

type Animal struct {
    Name string
    Age  int
    Zone int
}

我正在执行一个发布请求,发送一个json对象以将其解码为struct, json应该看起来像这样:

{
"Age":10,
"Name":"Lion", 
"Zone":1,
}

我希望所有字段都为字段,但是每当我不填写所有字段并发送一些json之类的

{
"Age":10,
"Zone":1,
}

json.Decoder自动构建该Filed并将其设置为""(该类型的值为零)而不是null。

如何设置空值或检查它是否为空并生成错误?

我希望结果为{Age:10, Zone:1, Name:null}或至少会产生错误!

这是我用来将json转换为struct的代码

animalModel := Animal{}
err := json.NewDecoder(r.Body).Decode(&animalModel)

2 个答案:

答案 0 :(得分:1)

您可以使用指针

type Animal struct {
    Name *string
    Age  int
    Zone int
}

或包裹

import "github.com/guregu/null"

type Animal struct {
    Name null.String
    Age  int
    Zone int
}

答案 1 :(得分:1)

string不能为零。如果要区分字段null和空值""的缺失,则可以使用以下选项:

  1. 作为一种快速的解决方案,您可以使用指针:
type Animal struct {
Name *string
}

缺点是您需要使用时间变量来设置此字段。

  1. 更灵活的解决方案是为Animal结构实现Unmarshaler接口,并使用时间map[string]string进行所需的检查并返回错误:
type Animal struct {
Name string
}

func (a *Animal) UnmarshalJSON(data []byte) error {
  m := map[string]interface{}{}
  err := json.Unmarshal(data, &m)
  if err != nil {
    return err
  }
  // check if field is exist
  name, exist := m["name"]
  if !exist {
    return fmt.Errorf("field 'name' should be present")
  }
  // check other fields...
  // ...

  // if all fields are ok, you can:
  // 1. set fields from map items
  a.Name = name
  ...

  // 2. call Unmarshal
  return json.Unmarshal(data, a)
}

这里的缺点是您需要“手动”检查每个字段。

  1. 下一步是使用重型机械:go-swaggergo-openapi。这些工具使您能够使用声明性架构(OpenAPI)对JSON数据执行检查,可以轻松实现版本控制,发布API等。 当然,对于3字段结构,这是过度设计。