Codegenerated struct validation tool for go.
gokay parses a struct and generates a Validate
method so that the struct implements the Validateable
interface. It does so by parsing the valid
tags in that struct's fields.
gokay generated Validate methods will return an ErrorMap that implements the Error interface. The ErrorMap is a map[string]error
containing failed validations for each invalid field in a struct.
godoc -http=:6060
This project uses Glide to manage it's dependencies. Please refer to the glide docs to see how to install and use glide.
This project is tested on go 1.7.1 and glide 0.12.1
mkdir -p $GOPATH/github.com/zencoder
cd $GOPATH/src/github.com/zencoder
git clone https://github.com/zencoder/gokay
cd gokay
glide install
go install ./...
gokay <file> [custom-generator-package custom-generator-contructor]
Generate validation methods for types in a single file
gokay file.go
Generate validation methods with a custom package and constructor
gokay file.go gkcustom NewCustomGKGenerator
gokay relies on the goimports tool to resolve import path of custom generator.
- Add validations to
valid
tag in struct def:
type ExampleStruct struct {
HexStringPtr *string `valid:"Length=(16),NotNil,Hex"`
HexString string `valid:"Length=(12),Hex"`
CanBeNilWithConstraints *string `valid:"Length=(12)"`
}
- Run gokay command
Validation tags are comma separated, with Validation parameters delimited by open and closed parentheses.
valid:"ValidationName1,ValidationName2=(vn2paramA)(vn2paramB)"
In the above example, the Hex
and NotNil
Validations are parameterless, whereas length requires 1 parameter.
Name | Params | Allowed Field Types | Description |
---|---|---|---|
Hex | N/A | (*)string |
Checks if a string field is a valid hexadecimal format number (0x prefix optional) |
NotNil | N/A | pointers | Checks and fails if a pointer is nil |
Length | 1 | (*)string |
Checks if a string's length matches the tag's parameter |
UUID | N/A | (*)string |
Checks and fails if a string is not a valid UUID |
These sections of code will be added to the generated Validate()
method regardless of a field's valid
tag's contents.
If a struct does not have any valid
tags and no fields with implicit validation rules, then no Validate method will be generated.
- Struct fields: generated code will call static Validate method on any field that implements Validateable interface
- Slice/Map fields: Static Validate will be called on each element of a slice or map of structs or struct pointers (one level of indirection). Only supports maps with string indices.
Note on built-in and implicit validations: With the obvious exception of NotNil, nil pointers fields are considered to be valid in order to allow support for optional fields.
gokay was built to allow developers to write and attach their own Validations to the Validate generator.
-
Write a function that validates a field. E.g:
// LengthString checks if the value of a string pointer has a length of exactly 'expected' func LengthString(expected int64, str *string) error { if str == nil { return nil // Covers the case where a value can be nil OR has a length constraint } if expected != int64(len(*str)) { return fmt.Errorf("Length was '%d', needs to be '%d'", len(*str), expected) } return nil }
-
Write a struct that implements the
Generater
interface// Generater defines the behavior of types that generate validation code type Generater interface { Generate(reflect.Type, reflect.StructField, []string) (string, error) Name() string }
- Name returns the string that will be used as a validation tag
-
GenerateValidationCode should generate a block will leverage the function defined in step 1. This block will be inserted into the generated
Validate
function. GenerateValidationCode output example:// ValidationName if err := somepackage.ValidationFunction(someparamA, someparamB, s.Field); err != nil { errorsField = append(errorsField, err) }
-
Write a function that constructs a
ValidateGenerator
. This function should live in a different package from your data model. Example:package gkcustom // To run: `gokay gkexample NewCustomValidator` func NewCustomGKGenerator() *gkgen.ValidateGenerator { v := gkgen.NewValidateGenerator() v.AddValidation(NewCustomValidator()) return v }
-
Write tests for your struct's constraints
-
Add
valid
tags to your struct fields -
Run gokay:
gokay file.go gkcustom NewCustomGKGenerator
Tested on go 1.7.1.
make test