Home > Enterprise >  Golang: Validate Struct Fields in Slice Items
Golang: Validate Struct Fields in Slice Items

Time:06-17

I'm new to Golang.

golang version: 1.17.8

validator: "github.com/go-playground/validator/v10"

I want to validate an incoming JSON payload after loaded into nested struct data structure. Here's my incoming JSON payload,

  {
  "name": "Yomiko",
  "address": {
    "city": "Tokyo",
    "street": "Shibaura St"
  },
  "children":[
    {
      "lastName": "Takayashi"
    }
  ],
  "isEmployed": false
  }

Here's my user.go file,

package main

type User struct {
    Name    string
    Address *Address `validate:"required"`
    Children []*Child
    IsEmployed *bool `validate:"required"`
}
type Address struct {
    City     string `validate:"required"`
    Street  string `validate:"required"`
}

type Child struct {
    Title string `validate:"required"`
    FirstName string
    LastName string `validate:"required"`
}

Here's my test function,

func TestUserPayload(t *testing.T) {
    actualUserPayload := NewUserPayloadFromFile("userpayload.json")

    validate := validator.New()
    err := validate.Struct(actualUserPayload)
    if err != nil {
        t.Error("Validation Error: ", err)
    }

}

This test passes. However, I expected it to fail as Child.Title is marked as required. I expected the following error,

Validation Error:  Key: 'Child.Title' Error:Field validation for 'Title' failed on the 'required' tag

However, when I loop through the children slice and validate each child struct as follows the test fails as expected,

func TestUserPayload(t *testing.T) {
    actualUserPayload := NewUserPayloadFromFile("userpayload.json")

    validate := validator.New()
    err := validate.Struct(actualUserPayload)
    if err != nil {
        t.Error("Validation Error: ", err)
    }

    children := actualUserPayload.Children

    for _, child := range children {
        err := validate.Struct(child)
        if err != nil {
            t.Error("Validation Error: ", err)
        }
    }

}

Is there a straightforward way to do this validation of the items in a slice of structs?

CodePudding user response:

According to the documentation of the validator package, you can use dive in your struct tag to get this behavior. This causes the validator to also validate the nested struct/slice/etc.

So you would need to update your User struct to this:

type User struct {
    Name       string
    Address    *Address `validate:"required"`
    Children   []*Child `validate:"dive"`
    IsEmployed *bool    `validate:"required"`
}

Here it is working in Go Playground

  • Related