validator 让后端代码更优雅 | 青训营笔记

64 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天

随着这次的青训营大项目接近尾声,回首自己刚开始写时的代码,发觉自己写的代码竟是如此的丑陋,尤其是以解析 JSON 获得相应的请求参数时。那么,有没有一种工具来帮助我们简洁优雅地完成从 *gin.Context 中解析获得参数并校验其时候符合预期要求呢。巧的是,golang 中正好就有这么一个工具—— validator。

概述

validator 是一个用于进行规则匹配、数据验证的包,其作为一个强大的数据校验工具在后端开发中得到了十分广泛地应用。

原理

通过在结构体 struct 中写入 validator 字段,再通过反射获取结构体 tag 进行数据验证。

安装

go get github.com/go-playground/validator/v10

常用tag

validator 的字段与 tag 众多,其中较为常用的有以下几种

  • excludesall:不能含有特殊符号
  • required:必填字段
  • numeric:字符串只包含普通字符
  • email:验证字符串是否是标准的邮箱格式
  • oneof:指必须为其中之一
  • url:验证字符串是否是标准的 url 格式
  • max:字符串最大长度
  • min:字符串最小长度
  • len:字符串固定长度
  • get:数字大于等于n
  • lte:三个一组小于n
  • ne:数字不等于n
  • eq:数字等于n
  • gt:数字大于n
  • lt:数字小于n

分隔符

  • , 分隔不同 tag
  • | 或操作
  • - 不进行 validator 验证

在大项目中的应用

这次的大项目接口还是略微有点多的,在使用 validator 进行数据校验后确实极大地简化了代码。以发布评论为例:

image.png

// ProxyPostComment 代理层
type ProxyPostComment struct {
   Token       string `form:"token"         validate:"required,jwt"`
   VideoId     int64  `form:"video_id"      validate:"required,numeric,min=1"`
   ActionType  int64  `form:"action_type"   validate:"required,numeric,oneof=1 2"`
   CommentText string `form:"comment_text"`
   CommentId   int64  `form:"comment_id"`
}

因为后面的 CommentText 与 CommentId 与 ActionType 有关,非必须,所以只用在前三个字段加上 required。
由于 ActionType 只能为 1 或 2 所以我们可以使用 oneof 进行约束\

后续的解析我们可以使用相应的方法来实现:

var p ProxyPostComment
// 参数绑定
err := ctx.ShouldBindQuery(&p)

// 参数校验
if err = common.Validate.Struct(p); err != nil {
   PostCommentFailed(ctx, err.Error())
   return
}