在上一个博客中,我们使用validator library在Golang中进行了结构验证。继续,在此博客中,我们将介绍自定义验证。
假设以下结构:
type Config struct {
ServerUrl string
AppPort int
}
我们可以使用图书馆提供的validations
来验证我们的结构:
import (
"fmt"
"github.com/go-playground/validator"
"strings"
)
func Validate(config Config) bool {
validate := validator.New()
validationErr := validate.Struct(config)
if validationErr != nil {
return false
}
return true
}
现在进入自定义验证的主题。
说,我们想检查ServerUrl
字段是否为HTTPS URL
直截了当的方法是引入一个函数:
func customValidator(config Config) bool {
value := config.ServerUrl
if !strings.HasPrefix(value, "https://") {
return false
}
return true
}
并记住在我们的Validate()
funcðâ€
,或者我们可以以惯用的方式做到这一点,并利用validator library€
然后自定义验证功能看起来像:
import (
"github.com/go-playground/validator"
"strings"
)
func CustomValidation(fl validator.FieldLevel) bool {
value := fl.Field().String()
if !strings.HasPrefix(value, "https://") {
return false
}
return true
}
“为什么这个怪异的功能签名?” ð您问 - 短暂地抓住这个问题...
下一步是向validator library注册我们的新规则。
import (
"fmt"
"github.com/go-playground/validator"
"strings"
)
func Validate(config Config) bool {
validate := validator.New()
// Registering the new rule "is_https" ...
err := validate.RegisterValidation("is_https", CustomValidation)
if err != nil {
fmt.Println("Error registering custom validation :", err.Error())
}
validationErr := validate.Struct(config)
if validationErr != nil {
return false
}
return true
}
现在我们的规则已注册,让我们将tag
附加到结构的字段:
type Config struct {
// Careful, the tag name should be identical to the one registered
ServerUrl string `validate:"is_https"`
AppPort int
}
和voilã! ð我们完成了!
现在,回到CustomValidation()
函数的怪异签名的问题 -
观察validate.RegisterValidation()
接收:
- 您想如何参考结构中的验证。
- a
validator.Func
-本质上是类型的函数:func(fl FieldLevel) bool
(reference source code)
甚至在结构级别的验证 - 涉及同一结构的多个字段的验证 - 可以通过相似的函数签名来实现:func(fl StructLevel) bool
这就是最终代码的样子:https://github.com/PankhudiB/go-config-validation/blob/main/configuration/custom_validation.go
愉快的编码! ð©ð»