关于go:一文了解Validator库

61次阅读

共计 3062 个字符,预计需要花费 8 分钟才能阅读完成。

1. 引言

github.com/go-playground/validator 是一个 Go 语言的库,用于对构造体字段进行验证。它提供了一种简略而灵便的形式来定义验证规定,并在验证过程中查看构造体字段是否满足这些规定。这个库能够用于验证各种数据,包含从用户输出到 API 申请中的数据,以确保数据的完整性和有效性。

在这篇文章中,咱们将从一个简略的问题登程,带你理解 Validator 库的用处,也会介绍Validator 的根本应用,同时也会介绍Validator 可能给咱们带来的长处。

2. 问题引入

在平时开发过程中,不论是 Web 应用程序来接管页面申请,还是创立一个服务来接管其余服务的申请,不可避免的,咱们都须要查看申请参数是否非法,是否无效。

假如咱们开发一个用户注册性能的 Web 应用程序。用户在注册页面上提供了以下信息:用户名、电子邮件地址、明码和确认明码。那么咱们必须编写下述代码,保障用户输出信息合法性,如下:

type User struct {
        Username string
        Email    string
}

func (u *User) checkUserIsInvalid() error {
    // 查看用户名长度是否非法
    if len(user.Username) < 3 || len(user.Username) > 20 {return errors.New("Invalid username length")
    }
    // 查看电子邮件地址是否非法
    if !isValidEmail(user.Email) {return errors.New("Invalid email address")
    }
    return nil
}
    
func registerUser(user User) error {
    // 查看输出是否非法
    err := user.checkUserIsInvalid()
    if err != nil {return errors.New("Invalid Input")
    }

    // 用户注册逻辑...
    return nil
}

这里的实现并没有太大的问题。然而如果程序中有 20 个中央,都查看了用户名长度是否非法,如果这个验证逻辑更简单一点,那就不太正当了,这里的一个做法是将验证逻辑抽取为一个函数,示例如下:

func checkUserNameIsValid(username string) bool{if len(username) < 3 || len(username) > 20 {return false}
    return true
}

而后用到这段逻辑的,间接调用该函数即可,不须要再反复实现,这个也可能解决一部分场景的问题。然而假想一下,如果咱们的验证逻辑不像下面那么简略,而是波及到多个字段的组合验证,类型转换,嵌套构造体的场景,这个时候咱们的验证逻辑会非常复杂。

比方咱们须要实现一个嵌套构造体的校验逻辑,此时咱们须要遍历每一个字段,可能会有十分深的 if…else 代码,亦或者比拟深层次的函数调用,这个简单逻辑不论是实现还是后续的浏览,都会破费咱们大量的精力。

回归到咱们的诉求,其实咱们并不是很关怀嵌套了多少层构造体,咱们更关注的是针对某一个 字段 / 值 ,其值是否满足咱们的预期。那有没有方法,做到咱们实现一个 验证逻辑 ,通过某种伎俩作用到 指标字段,而不须要去关注具体的数据结构,这样子既能做到验证逻辑的复用,同时也防止了对简单数据结构的解析,从而简化咱们的验证逻辑。

其实还真有,以后存在大量的验证库,可能帮忙咱们实现数据验证。接下来咱们就来理解下 Go 语言中的 Validator 库,其可能让咱们专一于 验证逻辑的编写,而不须要思考逻辑的复用以及简单数据结构的解决等许多问题,同时在某种程度上也进步了代码的可读性。

3. Validator 的根本应用

Validator 是基于标签来实现的,咱们只须要在构造体的字段上应用 validate 标签,而后设置标签值,每一个标签值代表一个验证规定。这些标签值将通知 validator 构造体的字段应该满足哪些条件,而后通过调用Validator 提供的 API,便可能实现数据的校验。

上面咱们通过一个简略的例子来进行阐明,帮忙咱们疾速入门Validator 库的应用:

type User struct {
   FirstName      string     `validate:"required"`
   LastName       string     `validate:"required"`
   Age            uint8      `validate:"gte=20,lte=60"`
   Email          string     `validate:"required,email"`
}

func main() {validate = validator.New()
   user := &User{
      FirstName:      "Badger",
      LastName:       "Smith",
      Age:            18,
      Email:          "Badger.Smith@gmail.com",
   }

   // returns nil or ValidationErrors ([]FieldError )
   err := validate.Struct(user)
   if err != nil {fmt.Println(err)
   }
}

下面例子中,咱们定义了一个 User 构造体,蕴含了不同类型的字段,每个字段都通过validate 标签定义一些验证规定。

其中FirstNameLastName 都设置了 required 规定,Age 设置了gte=0lte=130 规定,Email 则设置了requiredemail 两个规定。其中requiredgtelteemail 规定是 Validator 库自带的校验规定,能够间接设置。

在构造体设置好验证规定后,在 main 函数中通过New 办法创立一个 Validate 实例,而后通过调用Struct 办法,便会主动依据构造体标签设置的规定对对象的值进行验证。如果验证通过,将返回nil,否则会返回一个ValidationErrors 类型的谬误对象,其中蕴含验证失败的详细信息。

比方下面Age 字段不满足条件,此时user 对象将不能通过校验,会返回对应的错误信息,如下:

Key: 'User.Age' Error:Field validation for 'Age' failed on the 'gte' tag

4. Validator 长处

如果咱们应用 Validator 库,逻辑就能够抽取进去为一个公共的验证库,而后每一个验证逻辑对应一个验证规定名,这个Validator 库有反对,后续会讲述到。

而后在构造体中,应用validate 标签指定须要的验证规定,这样子咱们就不须要待验证数据的数据结构,也复用了验证规定,同时将验证规定与字段绑定到一起,也进步了代码的可读性。

通过应用 Validator 库,咱们可能回归到外围关注的内容, 验证传入数据的合法性, 而不是去解析数据结构,代码复用等一系列简单的事件,把这些简单的事件交给 Validator 帮咱们做。

5. 总结

本文介绍了 Go 语言中的 github.com/go-playground/validator 库,该库用于对构造体字段进行验证。文章从一个简略的问题登程,引入了Validator 库的应用。

之后介绍了 Validator 库的根本应用,包含如何创立验证实例、执行验证以及解决验证谬误。通过示例代码,演示了如何应用标签来设置验证规定,以及如何通过 Validator 库简化数据验证过程,进步代码的可读性和可维护性。

总的来说,在比较复杂的场景,通过应用 Validator 库,咱们能够专一于验证逻辑的编写,而不用放心数据结构的解析和反复的验证代码,可能很好得进步代码的可读性和可维护性。

正文完
 0