Skip to content

Latest commit

 

History

History
160 lines (116 loc) · 5.6 KB

README.md

File metadata and controls

160 lines (116 loc) · 5.6 KB

gokay CircleCI Coverage Status

Codegenerated struct validation tool for go.

How it works

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.

Code Documentation

godoc -http=:6060

Installing gokay

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.9.1 and glide 0.12.3

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 ./...

Running gokay

Usage

gokay <file> [custom-generator-package custom-generator-contructor]

Examples

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.

Using gokay

  • 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

Tag syntax

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.

Built-in Validations

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
NotEqual 1 (*)string or (*)number Checks and fails if field is equal to specific value
Set 1+ (*)string Checks and fails if field is not in a specific set of values

Implicitly generated validations

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.

Writing your own Validations

gokay was built to allow developers to write and attach their own Validations to the Validate generator.

  1. 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
    }
  2. 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
  3. 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)
    }
  4. 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
    }
  5. Write tests for your struct's constraints

  6. Add valid tags to your struct fields

  7. Run gokay: gokay file.go gkcustom NewCustomGKGenerator

More Examples

Development

Dependencies

Tested on go 1.7.1.

Build and run unit tests

make test

CI

This library builds on Circle CI, here.

License

Apache License Version 2.0