如何在GO中验证实体?

qco9c6ql  于 2023-06-19  发布在  Go
关注(0)|答案(2)|浏览(174)

如何在GO中进行验证?
互联网上的所有结果都建议我使用github.com/go-playground/validator/v10
但问题是,每当我把结构体传递给另一层或函数时,为了确保它是有效的,我必须一次又一次地调用validator.Struct()
我考虑直接在结构中验证(这是我在c#中通常做的方式),为了实现它,我为结构体创建了一个constructor,使所有字段都是私有的,并使用getter和setter(验证逻辑将在setter和构造函数内部),但问题是我不能使用gorm或mongodb将实体Map到表,因为所有的字段都是私有的,这些库不能读取私有字段,但是如果我不将它们设置为私有,我可能会意外地创建一个结构体,而不使用constructorsetter
在GO中如何处理实体验证?

2w3rbyxf

2w3rbyxf1#

您可以将结构设置为私有,但导出其字段。这样的话,人们需要调用带有私有结构的包的导出构造函数,以获取它的示例。
例如,您有一个存储包,它定义了结构类型,但未导出。此外,还创建了导出的构造函数。

package store

type foo struct { Name string }

func NewFoo(name string) foo { return foo{name} }

这样,包的用户需要调用构造函数来获取结构的示例。

package main

import "myorg.com/app/store"

func main() {
  f := store.NewFoo("gopher")
  fmt.Println(f.Name)
}

这并不是100%万无一失的,因为你仍然可以在那个商店包中搞砸,而且你的结构的用户可以在调用构造函数后更改名称。
如果您还想通过setter强制执行验证,您可能不会绕过某种帮助器结构。
在我看来:
也许你的想法太保守了。我通常很好地验证用户输入。在我的程序中,我并没有不断地验证自己。
另一件需要考虑的事情是,您可能需要抽象和松耦合。例如,一个带有gorm特定标签的结构体,可能只有你的存储层知道,而不是在整个应用程序中传递。从这个意义上说,您的验证可以进入store.CreateUser()或类似的文件。也许它也可以采用上面提到的帮助器结构。

bvuwiixz

bvuwiixz2#

如果你想在不使用GoValidator的情况下使用结构验证,你可以构建自己的自定义验证。检查下面的代码:
1 -使用私有字段和验证标签定义结构体:

type MyStruct struct {
    field1 string `validate:"required"`
    field2 int    `validate:"gte=0"`
}

2-为每个字段创建getter和setter方法:

func (s *MyStruct) GetField1() string {
    return s.field1
}

func (s *MyStruct) SetField1(value string) error {
    // Validate the value using your custom validation logic or a validation library
    if len(value) == 0 {
        return errors.New("field1 is required")
    }

    // Set the value if it passes validation
    s.field1 = value
    return nil
}

func (s *MyStruct) GetField2() int {
    return s.field2
}

func (s *MyStruct) SetField2(value int) error {
    // Validate the value using your custom validation logic or a validation library
    if value < 0 {
        return errors.New("field2 must be greater than or equal to 0")
    }

    // Set the value if it passes validation
    s.field2 = value
    return nil
}

3-在整个代码中使用这些getter和setter方法来访问和修改结构体字段。这可确保在设置值时始终应用验证逻辑。

obj := MyStruct{}
err := obj.SetField1("value1")
if err != nil {
    // Handle validation error
}

err = obj.SetField2(10)
if err != nil {
    // Handle validation error
}

// Access field values
value1 := obj.GetField1()
value2 := obj.GetField2()

相关问题