Introduction

You may have noticed that when we specify a struct, our rules can only validate its key-values or attributes. If we want to use the rules to completely validate the struct object, we find that we cannot register custom validation rules for the validation component. However, our validation component also supports directly validating the current struct object. Let’s look at an example where we need to perform complete custom validation on a user creation request and register a validation rule for UserCreateReq to achieve this.

Usage Example

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/gogf/gf/v2/database/gdb"
  6. "github.com/gogf/gf/v2/errors/gerror"
  7. "github.com/gogf/gf/v2/frame/g"
  8. "github.com/gogf/gf/v2/os/gctx"
  9. "github.com/gogf/gf/v2/util/gvalid"
  10. "time"
  11. )
  12. type UserCreateReq struct {
  13. g.Meta `v:"UserCreateReq"`
  14. Name string
  15. Pass string
  16. }
  17. func RuleUserCreateReq(ctx context.Context, in gvalid.RuleFuncInput) error {
  18. var req *UserCreateReq
  19. if err := in.Data.Scan(&req); err != nil {
  20. return gerror.Wrap(err, `Scan data to UserCreateReq failed`)
  21. }
  22. // SELECT COUNT(*) FROM `user` WHERE `name` = xxx
  23. count, err := g.Model("user").Ctx(ctx).Cache(gdb.CacheOption{
  24. Duration: time.Hour,
  25. Name: "",
  26. Force: false,
  27. }).Where("name", req.Name).Count()
  28. if err != nil {
  29. return err
  30. }
  31. if count > 0 {
  32. return gerror.Newf(`The name "%s" is already taken by others`, req.Name)
  33. }
  34. return nil
  35. }
  36. func main() {
  37. var (
  38. ctx = gctx.New()
  39. user = &UserCreateReq{
  40. Name: "john",
  41. Pass: "123456",
  42. }
  43. )
  44. err := g.Validator().RuleFunc("UserCreateReq", RuleUserCreateReq).Data(user).Run(ctx)
  45. fmt.Println(err)
  46. }

As you can see, by embedding g.Meta metadata into the struct and binding the custom rule UserCreateReq, when we validate the struct object through CheckStruct, we can use UserCreateReq to achieve validation.

After executing the above example, the terminal output:

  1. The name "john" is already taken