validator

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 6, 2021 License: Apache-2.0 Imports: 7 Imported by: 0

README

Golang ProtoBuf Validator Compiler

Apache 2.0 License

This package is a plugin that uses google protobuf validators to generate validation methods for grpc inputs. You can use this plugin with protoc utility.

Requirements

  • Go 1.13 or higher (recommended, although there is no problem using with earlier versions)
  • Protobuf

Usage

Declare a protobuf (version 3):

syntax = "proto3";
package protobuf.validator;
option go_package = ".;pb";
import "gitlab.yourypto.com/core/common-modules/protobuf-validator-go/validator.proto";

message SubMessage {
  // an integer, only little than 10 and greater than 0.
  int32 i = 1 [(validator.field) = {int_gt: 0, int_lt: 10}];
  // an integer, only little than or equal to  10 and greater than or equal to 0.
  double f = 2 [(validator.field) = {int_gte: 0, int_lte: 10}];
}

message MainMessage {
  // a string lowercase alpha-numeric of 8 to 20 characters.
  string username = 1 [(validator.field) = {regex: "^[a-z0-9]{8,20}$"}];
  // for mandatory fields use `msg_exist`, error if null.
  SubMessage msg = 2 [(validator.field) = {msg_exists : true}];
}

Using this package you don't have to change your generated codes.

Generated code
func (s *SubMessage) Validate() error {
    if !(s.I > 0) {
        return errors.New("validation failed, SubMessage.I must be greater than '0'")
    }
    if !(s.I < 10) {
        return fmt.Errorf("validation failed, SubMessage.I must be less than '10'")
    }
    if !(s.F >= 0) {
        return fmt.Errorf("validation failed, SubMessage.F must be greater than or equal to '0'")
    }
    if !(s.F <= 1) {
        return fmt.Errorf("validation failed, SubMessage.F must be less than or equal to '10'")
    }
    
    return nil
}

var _regex_Main_Username = regexp.MustCompile("^[a-z0-9]{5,30}$")

func (m *MainMessage) Validate() error {
    if !_regex_MainMessage_Username.MatchString(m.Username) {
        return fmt.Errorf("validation failed, MainMessage.Username must match to regex '^[a-z0-9]{8,20}$'")
    }
    if nil == m.Msg {
        return fmt.Errorf("validation failed: MainMessage.Msg message must exist")
    }
    if this.Inner != nil {
        if err := validators.CallValidatorIfExists(m.Msg); err != nil {
            return err
        }
    }

    return nil
}

Installing and using

When you want to compile your protobuf using protoc all of the plugins should have a binary in your $PATH. When you use go get for fetching this plugin package, a binary would be created in $GOBIN, so add $GOBIN to your $PATH:

export PATH=${PATH}:${GOPATH}/bin

The last step is adding some parameter for using the plugin, you can see an example here:

protoc  
  --proto_path=${GOPATH}/src 
  --proto_path=${GOPATH}/src/github.com/google/protobuf/src 
  --proto_path=. 
  --go_out=. 
  --govalidators_out=. 
  *.proto

The result is a grpc stub *.pb.go file plus message.validator.pb.go which validates your code. note that generated golang structures have a Validate method that returns an error.

License

protobuf-validator-go is released under the Apache 2.0 license. See the LICENSE file.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// optional validator.FieldValidator field = 65020;
	E_Field = &file_validator_proto_extTypes[0]
)

Extension fields to descriptorpb.FieldOptions.

View Source
var (
	// optional validator.OneofValidator oneof = 65021;
	E_Oneof = &file_validator_proto_extTypes[1]
)

Extension fields to descriptorpb.OneofOptions.

View Source
var File_validator_proto protoreflect.FileDescriptor

Functions

func CallValidatorIfExists

func CallValidatorIfExists(candidate interface{}) error

func FieldError

func FieldError(fieldName string, err error) error

FieldError wraps a given Validator error providing a message call stack.

Types

type FieldErrors

type FieldErrors struct {
	FieldStack []string
	NestedErr  error
}

FieldErrors ...

func (*FieldErrors) Error

func (f *FieldErrors) Error() string

type FieldValidator

type FieldValidator struct {

	// Uses a Golang RE2-syntax regex to match the field contents.
	Regex string `protobuf:"bytes,1,opt,name=regex,proto3" json:"regex,omitempty"`
	// Field value of integer strictly greater than this value.
	IntGt int64 `protobuf:"varint,2,opt,name=int_gt,json=intGt,proto3" json:"int_gt,omitempty"`
	// Field value of integer strictly smaller than this value.
	IntLt int64 `protobuf:"varint,3,opt,name=int_lt,json=intLt,proto3" json:"int_lt,omitempty"`
	// Used for nested message types, requires that the message type exists.
	MsgExists bool `protobuf:"varint,4,opt,name=msg_exists,json=msgExists,proto3" json:"msg_exists,omitempty"`
	// Human error specifies a user-customizable error that is visible to the user.
	HumanError string `protobuf:"bytes,5,opt,name=human_error,json=humanError,proto3" json:"human_error,omitempty"`
	// Field value of double strictly greater than this value.
	// Note that this value can only take on a valid floating point
	// value. Use together with float_epsilon if you need something more specific.
	FloatGt float64 `protobuf:"fixed64,6,opt,name=float_gt,json=floatGt,proto3" json:"float_gt,omitempty"`
	// Field value of double strictly smaller than this value.
	// Note that this value can only take on a valid floating point
	// value. Use together with float_epsilon if you need something more specific.
	FloatLt float64 `protobuf:"fixed64,7,opt,name=float_lt,json=floatLt,proto3" json:"float_lt,omitempty"`
	// Field value of double describing the epsilon within which
	// any comparison should be considered to be true. For example,
	// when using float_gt = 0.35, using a float_epsilon of 0.05
	// would mean that any value above 0.30 is acceptable. It can be
	// thought of as a {float_value_condition} +- {float_epsilon}.
	// If unset, no correction for floating point inaccuracies in
	// comparisons will be attempted.
	FloatEpsilon float64 `protobuf:"fixed64,8,opt,name=float_epsilon,json=floatEpsilon,proto3" json:"float_epsilon,omitempty"`
	// Floating-point value compared to which the field content should be greater or equal.
	FloatGte float64 `protobuf:"fixed64,9,opt,name=float_gte,json=floatGte,proto3" json:"float_gte,omitempty"`
	// Floating-point value compared to which the field content should be smaller or equal.
	FloatLte float64 `protobuf:"fixed64,10,opt,name=float_lte,json=floatLte,proto3" json:"float_lte,omitempty"`
	// Used for string fields, requires the string to be not empty (i.e different from "").
	StringNotEmpty bool `protobuf:"varint,11,opt,name=string_not_empty,json=stringNotEmpty,proto3" json:"string_not_empty,omitempty"`
	// Repeated field with at least this number of elements.
	RepeatedCountMin int64 `protobuf:"varint,12,opt,name=repeated_count_min,json=repeatedCountMin,proto3" json:"repeated_count_min,omitempty"`
	// Repeated field with at most this number of elements.
	RepeatedCountMax int64 `protobuf:"varint,13,opt,name=repeated_count_max,json=repeatedCountMax,proto3" json:"repeated_count_max,omitempty"`
	// Field value of length greater than this value.
	LengthGt int64 `protobuf:"varint,14,opt,name=length_gt,json=lengthGt,proto3" json:"length_gt,omitempty"`
	// Field value of length smaller than this value.
	LengthLt int64 `protobuf:"varint,15,opt,name=length_lt,json=lengthLt,proto3" json:"length_lt,omitempty"`
	// Field value of length strictly equal to this value.
	LengthEq int64 `protobuf:"varint,16,opt,name=length_eq,json=lengthEq,proto3" json:"length_eq,omitempty"`
	// Requires that the value is in the enum.
	IsInEnum bool `protobuf:"varint,17,opt,name=is_in_enum,json=isInEnum,proto3" json:"is_in_enum,omitempty"`
	// Ensures that a string value is in UUID format.
	// uuid_ver specifies the valid UUID versions. Valid values are: 0-5.
	// If uuid_ver is 0 all UUID versions are accepted.
	UuidVer int32 `protobuf:"varint,18,opt,name=uuid_ver,json=uuidVer,proto3" json:"uuid_ver,omitempty"`
	// contains filtered or unexported fields
}

func (*FieldValidator) Descriptor deprecated

func (*FieldValidator) Descriptor() ([]byte, []int)

Deprecated: Use FieldValidator.ProtoReflect.Descriptor instead.

func (*FieldValidator) GetFloatEpsilon

func (x *FieldValidator) GetFloatEpsilon() float64

func (*FieldValidator) GetFloatGt

func (x *FieldValidator) GetFloatGt() float64

func (*FieldValidator) GetFloatGte

func (x *FieldValidator) GetFloatGte() float64

func (*FieldValidator) GetFloatLt

func (x *FieldValidator) GetFloatLt() float64

func (*FieldValidator) GetFloatLte

func (x *FieldValidator) GetFloatLte() float64

func (*FieldValidator) GetHumanError

func (x *FieldValidator) GetHumanError() string

func (*FieldValidator) GetIntGt

func (x *FieldValidator) GetIntGt() int64

func (*FieldValidator) GetIntLt

func (x *FieldValidator) GetIntLt() int64

func (*FieldValidator) GetIsInEnum

func (x *FieldValidator) GetIsInEnum() bool

func (*FieldValidator) GetLengthEq

func (x *FieldValidator) GetLengthEq() int64

func (*FieldValidator) GetLengthGt

func (x *FieldValidator) GetLengthGt() int64

func (*FieldValidator) GetLengthLt

func (x *FieldValidator) GetLengthLt() int64

func (*FieldValidator) GetMsgExists

func (x *FieldValidator) GetMsgExists() bool

func (*FieldValidator) GetRegex

func (x *FieldValidator) GetRegex() string

func (*FieldValidator) GetRepeatedCountMax

func (x *FieldValidator) GetRepeatedCountMax() int64

func (*FieldValidator) GetRepeatedCountMin

func (x *FieldValidator) GetRepeatedCountMin() int64

func (*FieldValidator) GetStringNotEmpty

func (x *FieldValidator) GetStringNotEmpty() bool

func (*FieldValidator) GetUuidVer

func (x *FieldValidator) GetUuidVer() int32

func (*FieldValidator) ProtoMessage

func (*FieldValidator) ProtoMessage()

func (*FieldValidator) ProtoReflect

func (x *FieldValidator) ProtoReflect() protoreflect.Message

func (*FieldValidator) Reset

func (x *FieldValidator) Reset()

func (*FieldValidator) String

func (x *FieldValidator) String() string

type OneofValidator

type OneofValidator struct {

	// Require that one of the oneof fields is set.
	Required bool `protobuf:"varint,1,opt,name=required,proto3" json:"required,omitempty"`
	// contains filtered or unexported fields
}

func (*OneofValidator) Descriptor deprecated

func (*OneofValidator) Descriptor() ([]byte, []int)

Deprecated: Use OneofValidator.ProtoReflect.Descriptor instead.

func (*OneofValidator) GetRequired

func (x *OneofValidator) GetRequired() bool

func (*OneofValidator) ProtoMessage

func (*OneofValidator) ProtoMessage()

func (*OneofValidator) ProtoReflect

func (x *OneofValidator) ProtoReflect() protoreflect.Message

func (*OneofValidator) Reset

func (x *OneofValidator) Reset()

func (*OneofValidator) String

func (x *OneofValidator) String() string

type Validator

type Validator interface {
	Validate() error
}

Validator is a general interface that allows a message to be validated.

Directories

Path Synopsis
cmd
github.com
For each message there is one validator function, inside the functions , for each field there is a condition.
For each message there is one validator function, inside the functions , for each field there is a condition.
test

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL