Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

您好,请问,怎么实现从一个map数据源,使用Struct里定义好的规则来校验数据的有效性? #204

Open
regboy8 opened this issue Apr 26, 2023 · 8 comments
Assignees
Labels
question Further information is requested

Comments

@regboy8
Copy link

regboy8 commented Apr 26, 2023

怎么实现从一个map数据源,使用Struct里定义好的规则来校验数据的有效性?同时要校验成功后,可以把map的数据绑定到struct中?

主要的场景是在request中,需要将请求的数据绑定到定义好的struct中,绑定时使用struct中的规则来绑定,不符合就返回err,符合就绑定。

@inhere
Copy link
Member

inhere commented Apr 26, 2023

可以先绑定到 struct,再验证 struct 数据。

要想先验证再绑定,可以参考 https://github.com/gookit/validate/blob/master/README.zh-CN.md#%E9%AA%8C%E8%AF%81%E8%AF%B7%E6%B1%82 只是这样操作有点麻烦

@regboy8
Copy link
Author

regboy8 commented Apr 26, 2023

感谢回复!
v := data.Create() v.AddRule("name", "required")
单独这样一个个加太麻烦,我现在使用的是gozero这个框架,api的参数都是生成的,能否有方法可以读取结构,并根据结构上定义好的规则,导出验证的规则,然后把这个规则一次性添加到其他结构或者map上?

@inhere
Copy link
Member

inhere commented Apr 26, 2023

@regboy8
Copy link
Author

regboy8 commented Apr 26, 2023

可以的,直接验证结构体是没问题的,我现在主要的问题是把值赋值到结构体这一步想一起做,这一上可能更多的是类型不一致的问题,gozero这个框架,有参数校验的功能,但是出错时,他们的提示信息不友好,所以我一直想把这一步赋值到结构时的校验也集成在一起。
不然,看这条规则:
v.AddRule("id", "required,int"),这里限制id只能是整数,但这条规则好像起不了作用,因为结构赋值时如果不是int肯定会报错,所以int加与不加没什么意义,除非id这个属性的类型为string,这样规则才有意义。

@inhere
Copy link
Member

inhere commented Apr 26, 2023

它底层提供 validate interface 没有呢?像 gin 一样,可以直接嵌入 gookit/validate 替换默认的验证器。

在gin框架中使用

可以在任何框架中使用 validate,例如 Gin、Echo、Chi 等。 这里以 gin 示例:

package main
import (
    "github.com/gin-gonic/gin/binding"
    "github.com/gookit/validate"
)

// implements the binding.StructValidator
type customValidator struct {}

func (c *customValidator) ValidateStruct(ptr interface{}) error {
    v := validate.Struct(ptr)
    v.Validate() // 调用验证

    return v.Errors
}

func (c *customValidator) Engine() interface{} {
    return nil
}

func main()  {
	// ...

    // after init gin, set custom validator
    binding.Validator = &customValidator{}
}

@regboy8
Copy link
Author

regboy8 commented Apr 27, 2023

也有提供标准的Validator接口,但是也存在同样的问题,request的参数校验的规则同样也是需要手动的添加rule,我现在主要是不想手工写这一部分的规则,一来比较重复,二来维护也不方便,因为api在定义时就已经定义好了参数的各种约束条件了,如果可以直接从这个定义时获取规则来验证请求的参数的话,再加上api的自动生成,哪就完美了

@inhere
Copy link
Member

inhere commented Apr 27, 2023

api在定义时就已经定义好了参数的各种约束条件了,如果可以直接从这个定义时获取规则来验证请求的参数 这估计得你手动处理了,解析拿到规则配置到验证上。。。 我没用过 go-zero。或许你可以参考它内部的处理逻辑来调整下

@inhere inhere added the question Further information is requested label Apr 27, 2023
@regboy8
Copy link
Author

regboy8 commented Apr 27, 2023

是的,我现在的处理办法是不使用gozero的数据绑定逻辑,我自己写了一个,然后绑定时统一抛出标准的转换错误信息,因为折腾来折腾去发现,我其实只是想解决要绑定数据时错误的提示人性化点(狗头)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants