go validator struct字段校验

22 阅读1分钟

介绍

直入主题,接口参数校验dto的编写,一般偷懒会这样写:

type AddAppPermissionDTO struct {
	AppId       string `json:"appId" validate:"required"`
	Permissions []struct {
		DisplayName string  `json:"displayName" validate:"required,max=20"`
		ObjectCode  string  `json:"objectCode" validate:"required,max=30"`
		ActionCode  int8    `json:"actionCode" validate:"required,min=0"`
		Description *string `json:"description" validate:"max=200"`
	} `json:"permissions" validate:"required"`
}

Permissions字段的校验并不会生效,那么原因是:

validator标签默认只会校验结构体的顶层字段,不会自动遍历切片或子结构体进行递归校验。

所以Permissions字段的validate标签没有生效,需要加上dive关键字进行级联验证:

Permissions []struct { // 字段 } `validate:"dive"`

dive表示会自动遍历切片的每个元素并验证。

但是这里Permissions又是一个匿名结构体数组,dive无法递归进一步校验其中的字段。

完整的解决方案是:

  1. 定义权限的结构体:
type Permissions struct {
	DisplayName string  `json:"displayName" validate:"required,max=20"`
	ObjectCode  string  `json:"objectCode" validate:"required,max=30"`
	ActionCode  int8    `json:"actionCode" validate:"required,min=0"`
	Description *string `json:"description" validate:"max=200"`
}
  1. 在主结构体中使用切片和dive组合:
type AddAppPermissionDTO struct {
	AppId       string        `json:"appId" validate:"required"`
	Permissions []Permissions `json:"permissions" validate:"required,min=1,dive"`
}

完整结构为:

type Permissions struct {
	DisplayName string  `json:"displayName" validate:"required,max=20"`
	ObjectCode  string  `json:"objectCode" validate:"required,max=30"`
	ActionCode  int8    `json:"actionCode" validate:"required,min=0"`
	Description *string `json:"description" validate:"max=200"`
}

type AddAppPermissionDTO struct {
	AppId       string        `json:"appId" validate:"required"`
	Permissions []Permissions `json:"permissions" validate:"required,min=1,dive"`
}

总结:

好用,但是有点不好用