asaskevich / govalidator

[Go] Package of validators and sanitizers for strings, numerics, slices and structs
MIT License
6.05k stars 555 forks source link

Validate empty values #329

Closed zenovich closed 4 years ago

zenovich commented 5 years ago

Currently govalidator skips validation of zero numbers, empty strings, and other zero values of any type. It treats them as always valid. On the other hand, govalidator errs when a 'required' field has a zero value which disallows entering zero values into required fields.

The goal of this PR is to solve both problems: to validate zero values and to allow 'required' fields to have zero/empty values.

The main idea is to skip validation only when we are sure that a value is a nil-value (we can distinguish nil values from zero/empty values only for pointers, interfaces, maps, and slices; we consider all other values as non-nil values). All non-nil values are being validated. The 'required` validator errs only for nil values.

If one wants to check that some required string or number is given, he/she can declare them as pointers:

type MyStruct struct {
   Name     *string `valid:"required"`
   Number *int       `valid:"required"`
}

This will fail when Name and/or Number are not given or equal to nil.

When one wants to disallow empty strings, it's still possible to use the runelength validator. And there is also the range validator for numeric values.

This PR fixes #276, #274, (probably) #260, #256, #246, (probably) #149, (probably) #136, #130.

clems4ever commented 5 years ago

+1, I also faced the issue with *bool. When I set the value to false, the validator fails while I'm expecting it to fail only when the pointer is nil. Any hint to workaround while waiting for this PR to be considered and hopefully merged?

fushar commented 5 years ago

Hi, can we merge this PR? The issue with empty values is pretty annoying. Thanks!

asaskevich commented 4 years ago

Yes, I'm sorry for long awaiting. Merged, thank you everybody!

asaskevich commented 4 years ago

359 seems to be broken, need investigation

zenovich commented 4 years ago

359 seems to be broken, need investigation

As stated above “When one wants to disallow empty strings, it's still possible to use the runelength validator. And there is also the range validator for numeric values”

hanagantig commented 4 years ago

As stated above “When one wants to disallow empty strings, it's still possible to use the runelength validator. And there is also the range validator for numeric values”

It's not the same. I have this problem also. I just want to use my field as required, I don't want to worry about length, I just want to validate if my string empty or not.

zenovich commented 4 years ago

As stated above “When one wants to disallow empty strings, it's still possible to use the runelength validator. And there is also the range validator for numeric values”

It's not the same. I have this problem also. I just want to use my field as required, I don't want to worry about length, I just want to validate if my string empty or not.

"string is empty" means "string's length is equal to 0". There is some difference between the situation where the string is missing (what the 'required' validator checks) and the situation where the string value is given, but it is empty (what the length validators check).

zenovich commented 4 years ago

If one wants to check that some required string or number is given, he/she can declare them as pointers:

type MyStruct struct { Name string valid:"required" Number int valid:"required" }

hanagantig commented 4 years ago

If one wants to check that some required string or number is given, he/she can declare them as pointers: type MyStruct struct { Name string valid:"required" Number int valid:"required" }

What about this part of documentation ?

Custom error messages

Custom error messages are supported via annotations by adding the ~ separator - here's an example of how to use it:

type Ticket struct { Id int64 json:"id" FirstName string json:"firstname" valid:"required~First name is blank" }

zenovich commented 4 years ago

If one wants to check that some required string or number is given, he/she can declare them as pointers: type MyStruct struct { Name string valid:"required" Number int valid:"required" }

What about this part of documentation ?

Custom error messages Custom error messages are supported via annotations by adding the ~ separator - here's an example of how to use it: type Ticket struct { Id int64 json:"id" FirstName string json:"firstname" valid:"required~First name is blank" }

It looks like someone should update the documentation