:100:Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving

Package validator

Join the chat at https://gitter.im/go-playground/validator Project status Build Status Coverage Status Go Report Card GoDoc License

Package validator implements value validations for structs and individual fields based on tags.

It has the following unique features:

  • Cross Field and Cross Struct validations by using validation tags or custom validators.
  • Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated.
  • Ability to dive into both map keys and values for validation
  • Handles type interface by determining it's underlying type prior to validation.
  • Handles custom field types such as sql driver Valuer see Valuer
  • Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs
  • Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError
  • Customizable i18n aware error messages.
  • Default validator for the gin web framework; upgrading from v8 to v9 in gin see here

Installation

Use go get.

go get github.com/go-playground/validator/v10

Then import the validator package into your own code.

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

Error Return Value

Validation functions return type error

They return type error to avoid the issue discussed in the following, where err is always != nil:

Validator only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so:

err := validate.Struct(mystruct)
validationErrors := err.(validator.ValidationErrors)

Usage and documentation

Please see https://godoc.org/github.com/go-playground/validator for detailed usage docs.

Examples:

Baked-in Validations

Fields:

Tag Description
eqcsfield Field Equals Another Field (relative)
eqfield Field Equals Another Field
fieldcontains NOT DOCUMENTED IN doc.go
fieldexcludes NOT DOCUMENTED IN doc.go
gtcsfield Field Greater Than Another Relative Field
gtecsfield Field Greater Than or Equal To Another Relative Field
gtefield Field Greater Than or Equal To Another Field
gtfield Field Greater Than Another Field
ltcsfield Less Than Another Relative Field
ltecsfield Less Than or Equal To Another Relative Field
ltefield Less Than or Equal To Another Field
ltfield Less Than Another Field
necsfield Field Does Not Equal Another Field (relative)
nefield Field Does Not Equal Another Field

Network:

Tag Description
cidr Classless Inter-Domain Routing CIDR
cidrv4 Classless Inter-Domain Routing CIDRv4
cidrv6 Classless Inter-Domain Routing CIDRv6
datauri Data URL
fqdn Full Qualified Domain Name (FQDN)
hostname Hostname RFC 952
hostname_port HostPort
hostname_rfc1123 Hostname RFC 1123
ip Internet Protocol Address IP
ip4_addr Internet Protocol Address IPv4
ip6_addr Internet Protocol Address IPv6
ip_addr Internet Protocol Address IP
ipv4 Internet Protocol Address IPv4
ipv6 Internet Protocol Address IPv6
mac Media Access Control Address MAC
tcp4_addr Transmission Control Protocol Address TCPv4
tcp6_addr Transmission Control Protocol Address TCPv6
tcp_addr Transmission Control Protocol Address TCP
udp4_addr User Datagram Protocol Address UDPv4
udp6_addr User Datagram Protocol Address UDPv6
udp_addr User Datagram Protocol Address UDP
unix_addr Unix domain socket end point Address
uri URI String
url URL String
url_encoded URL Encoded
urn_rfc2141 Urn RFC 2141 String

Strings:

Tag Description
alpha Alpha Only
alphanum Alphanumeric
alphanumunicode Alphanumeric Unicode
alphaunicode Alpha Unicode
ascii ASCII
contains Contains
containsany Contains Any
containsrune Contains Rune
endswith Ends With
lowercase Lowercase
multibyte Multi-Byte Characters
number NOT DOCUMENTED IN doc.go
numeric Numeric
printascii Printable ASCII
startswith Starts With
uppercase Uppercase

Format:

Tag Description
base64 Base64 String
base64url Base64URL String
btc_addr Bitcoin Address
btc_addr_bech32 Bitcoin Bech32 Address (segwit)
datetime Datetime
e164 e164 formatted phone number
email E-mail String
eth_addr Ethereum Address
hexadecimal Hexadecimal String
hexcolor Hexcolor String
hsl HSL String
hsla HSLA String
html HTML Tags
html_encoded HTML Encoded
isbn International Standard Book Number
isbn10 International Standard Book Number 10
isbn13 International Standard Book Number 13
json JSON
latitude Latitude
longitude Longitude
rgb RGB String
rgba RGBA String
ssn Social Security Number SSN
uuid Universally Unique Identifier UUID
uuid3 Universally Unique Identifier UUID v3
uuid3_rfc4122 Universally Unique Identifier UUID v3 RFC4122
uuid4 Universally Unique Identifier UUID v4
uuid4_rfc4122 Universally Unique Identifier UUID v4 RFC4122
uuid5 Universally Unique Identifier UUID v5
uuid5_rfc4122 Universally Unique Identifier UUID v5 RFC4122
uuid_rfc4122 Universally Unique Identifier UUID RFC4122

Comparisons:

Tag Description
eq Equals
gt Greater than
gte Greater than or equal
lt Less Than
lte Less Than or Equal
ne Not Equal

Other:

Tag Description
dir Directory
endswith Ends With
excludes Excludes
excludesall Excludes All
excludesrune Excludes Rune
file File path
isdefault Is Default
len Length
max Maximum
min Minimum
oneof One Of
required Required
required_if Required If
required_unless Required Unless
required_with Required With
required_with_all Required With All
required_without Required Without
required_without_all Required Without All
excluded_with Excluded With
excluded_with_all Excluded With All
excluded_without Excluded Without
excluded_without_all Excluded Without All
unique Unique

Benchmarks

Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64
goos: darwin
goarch: amd64
pkg: github.com/go-playground/validator
BenchmarkFieldSuccess-8                                         20000000                83.6 ns/op             0 B/op          0 allocs/op
BenchmarkFieldSuccessParallel-8                                 50000000                26.8 ns/op             0 B/op          0 allocs/op
BenchmarkFieldFailure-8                                          5000000               291 ns/op             208 B/op          4 allocs/op
BenchmarkFieldFailureParallel-8                                 20000000               107 ns/op             208 B/op          4 allocs/op
BenchmarkFieldArrayDiveSuccess-8                                 2000000               623 ns/op             201 B/op         11 allocs/op
BenchmarkFieldArrayDiveSuccessParallel-8                        10000000               237 ns/op             201 B/op         11 allocs/op
BenchmarkFieldArrayDiveFailure-8                                 2000000               859 ns/op             412 B/op         16 allocs/op
BenchmarkFieldArrayDiveFailureParallel-8                         5000000               335 ns/op             413 B/op         16 allocs/op
BenchmarkFieldMapDiveSuccess-8                                   1000000              1292 ns/op             432 B/op         18 allocs/op
BenchmarkFieldMapDiveSuccessParallel-8                           3000000               467 ns/op             432 B/op         18 allocs/op
BenchmarkFieldMapDiveFailure-8                                   1000000              1082 ns/op             512 B/op         16 allocs/op
BenchmarkFieldMapDiveFailureParallel-8                           5000000               425 ns/op             512 B/op         16 allocs/op
BenchmarkFieldMapDiveWithKeysSuccess-8                           1000000              1539 ns/op             480 B/op         21 allocs/op
BenchmarkFieldMapDiveWithKeysSuccessParallel-8                   3000000               613 ns/op             480 B/op         21 allocs/op
BenchmarkFieldMapDiveWithKeysFailure-8                           1000000              1413 ns/op             721 B/op         21 allocs/op
BenchmarkFieldMapDiveWithKeysFailureParallel-8                   3000000               575 ns/op             721 B/op         21 allocs/op
BenchmarkFieldCustomTypeSuccess-8                               10000000               216 ns/op              32 B/op          2 allocs/op
BenchmarkFieldCustomTypeSuccessParallel-8                       20000000                82.2 ns/op            32 B/op          2 allocs/op
BenchmarkFieldCustomTypeFailure-8                                5000000               274 ns/op             208 B/op          4 allocs/op
BenchmarkFieldCustomTypeFailureParallel-8                       20000000               116 ns/op             208 B/op          4 allocs/op
BenchmarkFieldOrTagSuccess-8                                     2000000               740 ns/op              16 B/op          1 allocs/op
BenchmarkFieldOrTagSuccessParallel-8                             3000000               474 ns/op              16 B/op          1 allocs/op
BenchmarkFieldOrTagFailure-8                                     3000000               471 ns/op             224 B/op          5 allocs/op
BenchmarkFieldOrTagFailureParallel-8                             3000000               414 ns/op             224 B/op          5 allocs/op
BenchmarkStructLevelValidationSuccess-8                         10000000               213 ns/op              32 B/op          2 allocs/op
BenchmarkStructLevelValidationSuccessParallel-8                 20000000                91.8 ns/op            32 B/op          2 allocs/op
BenchmarkStructLevelValidationFailure-8                          3000000               473 ns/op             304 B/op          8 allocs/op
BenchmarkStructLevelValidationFailureParallel-8                 10000000               234 ns/op             304 B/op          8 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-8                         5000000               385 ns/op              32 B/op          2 allocs/op
BenchmarkStructSimpleCustomTypeSuccessParallel-8                10000000               161 ns/op              32 B/op          2 allocs/op
BenchmarkStructSimpleCustomTypeFailure-8                         2000000               640 ns/op             424 B/op          9 allocs/op
BenchmarkStructSimpleCustomTypeFailureParallel-8                 5000000               318 ns/op             440 B/op         10 allocs/op
BenchmarkStructFilteredSuccess-8                                 2000000               597 ns/op             288 B/op          9 allocs/op
BenchmarkStructFilteredSuccessParallel-8                        10000000               266 ns/op             288 B/op          9 allocs/op
BenchmarkStructFilteredFailure-8                                 3000000               454 ns/op             256 B/op          7 allocs/op
BenchmarkStructFilteredFailureParallel-8                        10000000               214 ns/op             256 B/op          7 allocs/op
BenchmarkStructPartialSuccess-8                                  3000000               502 ns/op             256 B/op          6 allocs/op
BenchmarkStructPartialSuccessParallel-8                         10000000               225 ns/op             256 B/op          6 allocs/op
BenchmarkStructPartialFailure-8                                  2000000               702 ns/op             480 B/op         11 allocs/op
BenchmarkStructPartialFailureParallel-8                          5000000               329 ns/op             480 B/op         11 allocs/op
BenchmarkStructExceptSuccess-8                                   2000000               793 ns/op             496 B/op         12 allocs/op
BenchmarkStructExceptSuccessParallel-8                          10000000               193 ns/op             240 B/op          5 allocs/op
BenchmarkStructExceptFailure-8                                   2000000               639 ns/op             464 B/op         10 allocs/op
BenchmarkStructExceptFailureParallel-8                           5000000               300 ns/op             464 B/op         10 allocs/op
BenchmarkStructSimpleCrossFieldSuccess-8                         3000000               417 ns/op              72 B/op          3 allocs/op
BenchmarkStructSimpleCrossFieldSuccessParallel-8                10000000               163 ns/op              72 B/op          3 allocs/op
BenchmarkStructSimpleCrossFieldFailure-8                         2000000               645 ns/op             304 B/op          8 allocs/op
BenchmarkStructSimpleCrossFieldFailureParallel-8                 5000000               285 ns/op             304 B/op          8 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8              3000000               588 ns/op              80 B/op          4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8     10000000               221 ns/op              80 B/op          4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailure-8              2000000               868 ns/op             320 B/op          9 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8      5000000               337 ns/op             320 B/op          9 allocs/op
BenchmarkStructSimpleSuccess-8                                   5000000               260 ns/op               0 B/op          0 allocs/op
BenchmarkStructSimpleSuccessParallel-8                          20000000                90.6 ns/op             0 B/op          0 allocs/op
BenchmarkStructSimpleFailure-8                                   2000000               619 ns/op             424 B/op          9 allocs/op
BenchmarkStructSimpleFailureParallel-8                           5000000               296 ns/op             424 B/op          9 allocs/op
BenchmarkStructComplexSuccess-8                                  1000000              1454 ns/op             128 B/op          8 allocs/op
BenchmarkStructComplexSuccessParallel-8                          3000000               579 ns/op             128 B/op          8 allocs/op
BenchmarkStructComplexFailure-8                                   300000              4140 ns/op            3041 B/op         53 allocs/op
BenchmarkStructComplexFailureParallel-8                          1000000              2127 ns/op            3041 B/op         53 allocs/op
BenchmarkOneof-8                                                10000000               140 ns/op               0 B/op          0 allocs/op
BenchmarkOneofParallel-8                                        20000000                70.1 ns/op             0 B/op          0 allocs/op

Complementary Software

Here is a list of software that complements using this library either pre or post validation.

  • form - Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.
  • mold - A general library to help modify or set data within data structures and other objects

How to Contribute

Make a pull request...

License

Distributed under MIT License, please see license file within the code for more details.

Owner
Go Playgound
multiple packages, libraries and programs to further the advancement of Go!
Go Playgound
Comments
  • How to validate `bool`

    How to validate `bool`

    type Thing struct {
      Truthiness bool `json:"truthiness" validate:"required"`
    }
    

    Using gin-gonic/gin with this, when it marshals JSON into a struct, this passes:

    { "truthiness": true }
    

    But this fails, b/c it is the golang zero-value for bool

    { "truthiness": false }
    

    I just want to validate that the property exists -- if it exists, I know it will have a value of true or false.

    Nothing obvious popped out at me from: https://godoc.org/gopkg.in/bluesuncorp/validator.v5#pkg-variables

  • cannot find package

    cannot find package "github.com/go-playground/validator/v10" in any of

    Package version eg. v8, v9:

    v10

    Issue, Question or Enhancement:

    go get github.com/go-playground/validator/v10
    

    give following error

    package github.com/go-playground/validator/v10: cannot find package "github.com/go-playground/validator/v10" in any of:
            /usr/local/go/src/github.com/go-playground/validator/v10 (from $GOROOT)
            /go/src/github.com/go-playground/validator/v10 (from $GOPATH)
    
    

    Code sample, to showcase or reproduce:

    using golang docker latest

    $ docker run -it --rm golang sh
    $ go get github.com/go-playground/validator/v10
    package github.com/go-playground/validator/v10: cannot find package "github.com/go-playground/validator/v10" in any of:
            /usr/local/go/src/github.com/go-playground/validator/v10 (from $GOROOT)
            /go/src/github.com/go-playground/validator/v10 (from $GOPATH)
    
  • Add validation functions for tcp/udp/ip/unix addresses

    Add validation functions for tcp/udp/ip/unix addresses

    What do you think of those fileds? If you think it's good idea I can create some docs + tests.

    Why I think is good? I constatly need to parse some bind addreses for other services (http, etc....) and would be nice to validate those adresses, not it time when service will be starded.

  • Dive into and validate map keys?

    Dive into and validate map keys?

    Package version eg. v8, v9:

    v9

    Issue, Question or Enhancement:

    Question

    Code sample, to showcase or reproduce:

    
    package main
    
    import (
        "fmt"
        "gopkg.in/go-playground/validator.v9"
    )
    
    type LangCode string
    type Label map[LangCode]string
    
    type TestMapStructPtr struct {
        Label Label `validate:"lang_code,dive,required"`
    }
    
    var validate *validator.Validate
    
    func main() {
    
        validate = validator.New()
        validate.RegisterValidation("lang_code", ValidLangCode)
    
        label := Label {
            "en":"Good morning!",
            "pt":"Bom dia!",
            "es":"¡Buenos días!",
            "is":"Góðan daginn",
        }
    
        err := validate.Struct(TestMapStructPtr{label})
        // hoping to catch that "is" key is not valid
        if err != nil {
            fmt.Printf("label not valid! %s\n", err)
        }
    }
    
    func ValidLangCode(fl validator.FieldLevel) bool {
        validLangCodes := map[string]bool{
            "en":true,
            "es":true,
            "pt":true,
        }
        fmt.Printf("Validating %s\n", fl.Field())
        return validLangCodes[fl.Field().String()]
    }
    

    Hello, I am very new to the validator so I apologize if I've misinterpreted the use of dive and maps! I'm also aware the above can be accomplished with Label as a struct, but I'm wondering if validator supports validating map keys using custom validations.

    Is there a way to validate the keys of a map?

    The above code example, I was expecting the validation rule "lang_code,dive,required" would validate each map key against the lang_code validation, and the value as required.

    However, running the above code I see that ValidLangCode is receiving the entire map, not each key. Is there any way to dive into the keys? Trying other combinations of dive, lang_code, and required didn't seem to work.

    thanks!

  • Validate nested structs

    Validate nested structs

    Fixes #367 .

    Make sure that you've checked the boxes below before you submit PR:

    • [x] Tests exist or have been written that cover this particular change.

    Change Details: This change allows using (any: custom or backed in) validations on nested structs.

    @go-playground/admins

  • required_without does not work with pointers

    required_without does not work with pointers

    Package version eg. v8, v9:

    v9

    Issue, Question or Enhancement:

    required_without does not work with pointers

    Code sample, to showcase or reproduce:

    Playground: https://play.golang.org/p/5hpXOfDJU4V

    package main
    
    import (
    	"fmt"
    	"gopkg.in/go-playground/validator.v9"
    )
    
    type a struct {
    	Field1 *string `validate:"required_without=Field2"`
    	Field2 *int    `validate:"required_without=Field1"`
    }
    
    func main() {
    	validate := validator.New()
    
    	testStr := new(string)
    	*testStr = "abcd"
    
    	testInt := new(int)
    	*testInt = 42
    
    	if err := validate.Struct(a{Field1: testStr}); err != nil {
    		fmt.Println(err)
    	} else {
    		fmt.Println("Test A OK")
    	}
    
    	if err := validate.Struct(a{Field2: testInt}); err != nil {
    		fmt.Println(err)
    	} else {
    		fmt.Println("Test B OK")
    	}
    
    	if err := validate.Struct(a{Field1: testStr, Field2: testInt}); err != nil {
    		fmt.Println(err)
    	} else {
    		fmt.Println("Test C OK")
    	}
    }
    
  • Add NotBlank validation function.

    Add NotBlank validation function.

    Change Details:

    • There are cases when a value needs to not be empty (like a string containing only spaces, slice not nil but with no elements) and I added a new tag to easily overcome this need.
    type TestString struct {
    	NotBlank  string `validate:"notblank"`
    }
    

    @go-playground/admins

  • Is it possible to have a required cross-field validation?

    Is it possible to have a required cross-field validation?

    Hi @joeybloggs, I'm using your package to perform some validation on data that I'm receiving via API.

    I'd like to know if there is the possibility (and I missed it) to perform a required cross-field validation.

    What I want to achieve is having a validation that returns OK if one of two fields is present on my struct...something like this:

    type Field struct {
       Value1 string `validate:"at_least_one_required"`
       Value2 string `validate:"at_least_one_required"`
       ...
    }
    

    and the validator returns an error if no one of the two fields is not set up.

    Is that possible?

    Thanks, Marco

  • validate.Struct() always return error

    validate.Struct() always return error

    hi, i am new in golang, maybe that problem about me.

    when i use validator.Struct() in a function that return named error, the err var always not nil

    func ValidateStruct(v interface{}) (err error) {
        err = validate.Struct(v)
        return
    }
    

    but when i use it like this, it works

    func ValidateStruct(v interface{}) (err error) {
        errs := validate.Struct(v)
        if errs != nil {
            err = errs
            return
        }
        return nil
    }
    

    so what the problem ?

  • Let validators see current fields paths

    Let validators see current fields paths

    Fixes Or Enhances # .

    Make sure that you've checked the boxes below before you submit PR:

    • [x] Tests exist or have been written that cover this particular change.

    Change Details:

    Currently there is no way for validators to know which fields they are checking. So validators depending not only on the value, but on the field itself (e.g. checking that the field is listed in some external source) cannot work.

    This PR adds new methods Path() & StructPath() into the FieldLevel interface allowing validators to get a path (based on FieldName-s) or a struct path (based on StructFieldName-s) of the current field respectively.

    @go-playground/admins

  • Add Valuer interface support

    Add Valuer interface support

    The Valuer interface in the sql/driver package seems like one of the primary ways for SQL drivers and ORMs to interact with databases, particularly when NULL values are a possibility.

    It would be great if the validator could apply validations directly to Value() values in the case of a type that supports the interface. This would make validations on values of type sql.NullXXX much more straightforward.

    BTW - Thanks for making this package. It's been very handy.

  • fix: typo

    fix: typo

    Fixes Or Enhances

    Make sure that you've checked the boxes below before you submit PR:

    • [x] Tests exist or have been written that cover this particular change.

    @go-playground/validator-maintainers

  • feat(unique): Add support for struct memember validation

    feat(unique): Add support for struct memember validation

    Fixes Or Enhances

    Issue #1034

    This allows validating that two struct members are unique. This has been documented as a feature but has never been implemented.

    Make sure that you've checked the boxes below before you submit PR:

    • [x] Tests exist or have been written that cover this particular change.

    @go-playground/validator-maintainers

  • Added

    Added "http_url" tag to validate if the variable is a HTTP(s) URL

    Enhances

    In most cases, the application only accepts the HTTP URL as input. But we don't have a suitable tag to validate it.

    For example, application use url tag to validate the user input then use it as the cURL's parameter to download a network file:

    package main
    
    import (
    	"os"
    	"os/exec"
    
    	"github.com/go-playground/validator/v10"
    )
    
    func main() {
    	var input = os.Args[1]
    	var v = validator.New()
    	err := v.Var(input, "url")
    	if err != nil {
    		panic(err)
    	}
    
    	cmd := exec.Command("curl", input)
    	cmd.Stdout = os.Stdout
    	cmd.Stderr = os.Stderr
    	err = cmd.Run()
    	if err != nil {
    		panic(err)
    	}
    }
    

    But it's not safe if user use file:///etc/passwd as the input, it will download the local file unexpected.

    So I added a new tag named "http_url" to enhance the current situation.

    Make sure that you've checked the boxes below before you submit PR:

    • [ ] Tests exist or have been written that cover this particular change.

    @go-playground/validator-maintainers

  • Add cron support

    Add cron support

    Fixes Or Enhances

    Make sure that you've checked the boxes below before you submit PR:

    • [x] Tests exist or have been written that cover this particular change.

    @go-playground/validator-maintainers

  • Nested Struct Validation Fails

    Nested Struct Validation Fails

    • [x] I have looked at the documentation here first? Yes
    • [x] I have looked at the examples provided that may showcase my question here? Yes

    Package version eg. v9, v10:

    v10

    Issue, Question or Enhancement:

    I have a nested struct as demonstrated below and when I utilize this type of structure validation fails.

    Code sample, to showcase or reproduce:

    package common
    
    type Equipment struct {
    	ID            int32           `json:"id"`
    	URL           string          `json:"url"`
    	Name          string          `json:"name"`
    	Hostname      string          `json:"hostname"`
    	Network       Network         `json:"network"`
    	State         State           `json:"equipment_state"`
    	OS            OS              `json:"os"`
    	Role          Role            `json:"role"`
    	Platform      Platform        `json:"platform"`
    }
    
    package model
    
    //Equipment Represent the data model returned from ESDB
    type Equipment struct {
    	common.Equipment
    	OutputModel OutputType
    }
    
    

    Basically the struct in model extends the object defined in common and I use it in my code.

    If I create a struct using the common entity it works fine but if I use the model version it fails. Here's the code I used to test the validation.

    	obj := common.Equipment{}
    	obj.Role = 5
    
    	v := validator.New()
    	rules := map[string]string{
    		"Role": "min=99,max=200",
    	}
    	v.RegisterStructValidationMapRules(rules, common.Equipment{})
    
    	err := v.Struct(obj)
    	if err != nil {
    		for _, e := range err.(validator.ValidationErrors) {
    			fmt.Println(e)
    		}
    	}
    
    

    For reference, Role is an Int.

    type Role int
    
    const (
    	CoreRouter Role = iota + 1
    	AuxiliarySwitch
    	OLS
    	// ...etc more entries here.
    )
    
  • Validating Array of struct

    Validating Array of struct

    Hello guys, and sorry to ask it. I'm not used to go and I'm trying to learn...

    I have the following JSON that I need to validate:

    [
        {
            "requested_id": "bookata_XY123",
            "check_in": "2020-01-01",
            "nights": 5,
            "selling_rate": 200,
            "margin": 20
        },
       {
            "requested_id": "bookata_XY123",
            "check_in": "2020-01-01",
            "nights": 5,
            "selling_rate": 200,
            "margin": 20
        }
    ]
    

    And I have the following structure:

    type Stat struct {
    	RequestedId string json:"requested_id" validate:"required"
            Checkin     string json:"check_in" validate:"required"
    	Nights      int16  json:"nights" validate:"required,numeric"
    	SellingRate int16  json:"selling_rate" validate:"required,numeric"
    	Margin      int16  json:"margin" validate:"required,numeric"
    }
    

    Whenever I try to validate it I received the following error: *error is validator.invalid validationerror not validator.validationerrors and the reason is: validator: (nil []domain.Stat) which is not true because I can see it has all the data inside the struct, and I'm using the following code:

            var stats []domain.Stat
    	ctx.BodyParser(&stats)
    
    	err := Validator.Struct(stats)
    
    	if err != nil {
    		if _, ok := err.(*validator.InvalidValidationError); ok {
    			fmt.Println(err)
    			return err
    		}
    		for _, err := range err.(validator.ValidationErrors) {
    			var el IError
    			el.Field = err.Field()
    			el.Tag = err.Tag()
    			el.Value = err.Param()
    			errors = append(errors, &el)
    		}
    
    		return ctx.Status(fiber.StatusBadRequest).JSON(errors)
    	}
    

    But if I change the code to:

     stat := domain.Stat
     err := Validator.Struct(stat)
    

    It works as expected. What am I doing wrong here? Thank you!

An interesting go struct tag expression syntax for field validation, etc.

go-tagexpr An interesting go struct tag expression syntax for field validation, etc. Usage Validator: A powerful validator that supports struct tag ex

Jan 9, 2023
An idiomatic Go (golang) validation package. Supports configurable and extensible validation rules (validators) using normal language constructs instead of error-prone struct tags.

ozzo-validation Description ozzo-validation is a Go package that provides configurable and extensible data validation capabilities. It has the followi

Jan 7, 2023
Dec 28, 2022
Struct validation using tags

Govalid Use Govalid to validate structs. Documentation For full documentation see pkg.go.dev. Example package main import ( "fmt" "log" "strings"

Dec 6, 2022
Library providing opanapi3 and Go types for store/validation and transfer of ISO-4217, ISO-3166, and other types.

go-types This library has been created with the purpose to facilitate the store, validation, and transfer of Go ISO-3166/ISO-4217/timezones/emails/URL

Nov 9, 2022
Swagger builder and input validation for Go servers
Swagger builder and input validation for Go servers

crud A Swagger/OpenAPI builder and validation library for building HTTP/REST APIs. Heavily inspired by hapi and the hapi-swagger projects. No addition

Jan 5, 2023
Go package containing implementations of efficient encoding, decoding, and validation APIs.

encoding Go package containing implementations of encoders and decoders for various data formats. Motivation At Segment, we do a lot of marshaling and

Dec 25, 2022
Validate Golang request data with simple rules. Highly inspired by Laravel's request validation.
Validate Golang request data with simple rules. Highly inspired by Laravel's request validation.

Validate golang request data with simple rules. Highly inspired by Laravel's request validation. Installation Install the package using $ go get githu

Dec 29, 2022
Opinionated go to validation library

?? valeed Your opinionated go-to validation library. Struct tag-based. Validate here, validate there, validate everywhere. Sleek and simple validation

Jul 21, 2022
Simple module for validation inn control number

simple module for validation inn control number

Sep 4, 2022
Gin Middleware to extract json tag value from playground validator's errors validation

Json Tag Extractor for Go-Playground Validator This is Gin Middleware that aim to extract json tag and than store it to FieldError.Field() object. Ins

Jan 14, 2022
Validator - Replace the validation framework used by gin

validator Replace the validation framework used by gin replace mod:replace githu

Jan 18, 2022
:balloon: A lightweight struct validator for Go

gody Go versions supported Installation go get github.com/guiferpa/gody/v2 Usage package main import ( "encoding/json" "fmt" "net/http"

Nov 19, 2022
[Go] Package of validators and sanitizers for strings, numerics, slices and structs

govalidator A package of validators and sanitizers for strings, structs and collections. Based on validator.js. Installation Make sure that Go is inst

Jan 6, 2023
Provide check digit algorithms and calculators written in Go

checkdigit About Provide check digit algorithms and calculators written by Go. Provided methods Algorithms Luhn Verhoeff Damm Calculators ISBN-10 ISBN

Dec 17, 2022
A norms and conventions validator for Terraform

This tool will help you ensure that a terraform folder answer to your norms and conventions rules. This can be really useful in several cases : You're

Nov 29, 2022
The Hyperscale InputFilter library provides a simple inputfilter chaining mechanism by which multiple filters and validator may be applied to a single datum in a user-defined order.

Hyperscale InputFilter Branch Status Coverage master The Hyperscale InputFilter library provides a simple inputfilter chaining mechanism by which mult

Oct 20, 2021
💯 Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving

Package validator implements value validations for structs and individual fields based on tags.

Nov 9, 2022
Golang parameter validation, which can replace go-playground/validator, includes ncluding Cross Field, Map, Slice and Array diving, provides readable,flexible, configurable validation.
Golang parameter validation, which can replace go-playground/validator, includes ncluding Cross Field, Map, Slice and Array diving, provides readable,flexible, configurable validation.

Checker 中文版本 Checker is a parameter validation package, can be use in struct/non-struct validation, including cross field validation in struct, elemen

Dec 16, 2022
Convert struct, slice, array, map or others for Golang

XConv zh-CN XConv is a golang type convertor. It convert any value between types (base type, struct, array, slice, map, etc.) Features Convert between

Dec 8, 2022