Return 来自结构标签验证的自定义错误消息
Return custom error message from struct tag validation
我将 Go 1.17 与 Gin 一起使用,我想在将数据发送到我的数据库之前实施结构验证。我以 Gin documentation.
为例
在结构中,我们可以声明不同的标签来验证这样的字段:
type User struct {
FirstName string `json:"first_name" binding:"required"`
LastName string `json:"last_name" binding:"required"`
Age uint8 `json:"age" binding:"gte=0,lte=130"`
Email string `json:"email" binding:"required,email"`
FavouriteColor string `json:"favourite_color" binding:"iscolor"`
}
在处理程序中,我可以像这样抓取错误:
var u User
if err := c.ShouldBindWith(&u, binding.Query); err == nil {
c.JSON(http.StatusOK, gin.H{"message": "Good Job"})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
错误消息将是:
{
"error": "Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'required' tag\nKey: 'User.LastName' Error:Field validation for 'LastName' failed on the 'required' tag\nKey: 'User.Email' Error:Field validation for 'Email' failed on the 'required' tag\nKey: 'User.FavouriteColor' Error:Field validation for 'FavouriteColor' failed on the 'iscolor' tag"
}
错误消息太冗长了,怎么可能 returns 向用户提供更好的错误信息?我想将 json 响应建模为:
{
"errors": [
"first_name": "This field is required",
"last_name": "This field is required",
"age": "This field is required",
"email": "Invalid email"
]
}
Gin gonic 使用包 github.com/go-playground/validator/v10
来执行绑定验证。如果验证失败,返回的错误是 validator.ValidationErrors
.
这没有明确提及,但在 Model binding and validation 中指出:
Gin uses go-playground/validator/v10 for validation. Check the full docs on tags usage here.
链接到 go-playground/validator/v10
文档,您可以在其中找到段落 Validation Functions Return Type error。
您可以使用标准的 errors
包来检查错误是否是那个,将其解包,然后访问单个字段,即 validator.FieldError
。由此,您可以构造任何您想要的错误消息。
给出这样的错误模型:
type ApiError struct {
Field string
Msg string
}
你可以这样做:
var u User
err := c.BindQuery(&u);
if err != nil {
var ve validator.ValidationErrors
if errors.As(err, &ve) {
out := make([]ApiError, len(ve))
for i, fe := range ve {
out[i] = ApiError{fe.Field(), msgForTag(fe.Tag())}
}
c.JSON(http.StatusBadRequest, gin.H{"errors": out})
}
return
}
使用辅助函数为您的验证规则输出自定义错误消息:
func msgForTag(tag string) string {
switch tag {
case "required":
return "This field is required"
case "email":
return "Invalid email"
}
return ""
}
在我的测试中,输出:
{
"errors": [
{
"Field": "Number",
"Msg": "This field is required"
}
]
}
PS:要获得带有动态键的 json 输出,您可以使用 map[string]string
而不是固定结构模型。
我将 Go 1.17 与 Gin 一起使用,我想在将数据发送到我的数据库之前实施结构验证。我以 Gin documentation.
为例在结构中,我们可以声明不同的标签来验证这样的字段:
type User struct {
FirstName string `json:"first_name" binding:"required"`
LastName string `json:"last_name" binding:"required"`
Age uint8 `json:"age" binding:"gte=0,lte=130"`
Email string `json:"email" binding:"required,email"`
FavouriteColor string `json:"favourite_color" binding:"iscolor"`
}
在处理程序中,我可以像这样抓取错误:
var u User
if err := c.ShouldBindWith(&u, binding.Query); err == nil {
c.JSON(http.StatusOK, gin.H{"message": "Good Job"})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
错误消息将是:
{
"error": "Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'required' tag\nKey: 'User.LastName' Error:Field validation for 'LastName' failed on the 'required' tag\nKey: 'User.Email' Error:Field validation for 'Email' failed on the 'required' tag\nKey: 'User.FavouriteColor' Error:Field validation for 'FavouriteColor' failed on the 'iscolor' tag"
}
错误消息太冗长了,怎么可能 returns 向用户提供更好的错误信息?我想将 json 响应建模为:
{
"errors": [
"first_name": "This field is required",
"last_name": "This field is required",
"age": "This field is required",
"email": "Invalid email"
]
}
Gin gonic 使用包 github.com/go-playground/validator/v10
来执行绑定验证。如果验证失败,返回的错误是 validator.ValidationErrors
.
这没有明确提及,但在 Model binding and validation 中指出:
Gin uses go-playground/validator/v10 for validation. Check the full docs on tags usage here.
链接到 go-playground/validator/v10
文档,您可以在其中找到段落 Validation Functions Return Type error。
您可以使用标准的 errors
包来检查错误是否是那个,将其解包,然后访问单个字段,即 validator.FieldError
。由此,您可以构造任何您想要的错误消息。
给出这样的错误模型:
type ApiError struct {
Field string
Msg string
}
你可以这样做:
var u User
err := c.BindQuery(&u);
if err != nil {
var ve validator.ValidationErrors
if errors.As(err, &ve) {
out := make([]ApiError, len(ve))
for i, fe := range ve {
out[i] = ApiError{fe.Field(), msgForTag(fe.Tag())}
}
c.JSON(http.StatusBadRequest, gin.H{"errors": out})
}
return
}
使用辅助函数为您的验证规则输出自定义错误消息:
func msgForTag(tag string) string {
switch tag {
case "required":
return "This field is required"
case "email":
return "Invalid email"
}
return ""
}
在我的测试中,输出:
{
"errors": [
{
"Field": "Number",
"Msg": "This field is required"
}
]
}
PS:要获得带有动态键的 json 输出,您可以使用 map[string]string
而不是固定结构模型。