diff options
Diffstat (limited to 'vendor/github.com/mwitkow/go-proto-validators/README.md')
-rw-r--r-- | vendor/github.com/mwitkow/go-proto-validators/README.md | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/vendor/github.com/mwitkow/go-proto-validators/README.md b/vendor/github.com/mwitkow/go-proto-validators/README.md new file mode 100644 index 0000000000..e0a49e7dd4 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/README.md @@ -0,0 +1,141 @@ +# Golang ProtoBuf Validator Compiler + +[](https://travis-ci.org/mwitkow/go-proto-validators) +[](LICENSE) + +A `protoc` plugin that generates `Validate() error` functions on Go proto `struct`s based on field options inside `.proto` +files. The validation functions are code-generated and thus don't suffer on performance from tag-based reflection on +deeply-nested messages. + +## Requirements + +Using Protobuf validators is currently verified to work with: + +- Go 1.11 & 1.12 +- [Protobuf](https://github.com/protocolbuffers/protobuf) @ `v3.8.0` +- [Go Protobuf](https://github.com/golang/protobuf) @ `v1.3.2` +- [Gogo Protobuf](https://github.com/gogo/protobuf) @ `v1.3.0` + +It _should_ still be possible to use it in project using earlier Go versions. However if you want to contribute to this +repository you'll need at least 1.11 for Go module support. + +## Paint me a code picture + +Let's take the following `proto3` snippet: + +```proto +syntax = "proto3"; +package validator.examples; +import "github.com/mwitkow/go-proto-validators/validator.proto"; + +message InnerMessage { + // some_integer can only be in range (1, 100). + int32 some_integer = 1 [(validator.field) = {int_gt: 0, int_lt: 100}]; + // some_float can only be in range (0;1). + double some_float = 2 [(validator.field) = {float_gte: 0, float_lte: 1}]; +} + +message OuterMessage { + // important_string must be a lowercase alpha-numeric of 5 to 30 characters (RE2 syntax). + string important_string = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; + // proto3 doesn't have `required`, the `msg_exist` enforces presence of InnerMessage. + InnerMessage inner = 2 [(validator.field) = {msg_exists : true}]; +} +``` + +First, the **`required` keyword is back** for `proto3`, under the guise of `msg_exists`. The painful `if-nil` checks are taken care of! + +Second, the expected values in fields are now part of the contract `.proto` file. No more hunting down conditions in code! + +Third, the generated code is understandable and has clear understandable error messages. Take a look: + +```go +func (this *InnerMessage) Validate() error { + if !(this.SomeInteger > 0) { + return fmt.Errorf("validation error: InnerMessage.SomeInteger must be greater than '0'") + } + if !(this.SomeInteger < 100) { + return fmt.Errorf("validation error: InnerMessage.SomeInteger must be less than '100'") + } + if !(this.SomeFloat >= 0) { + return fmt.Errorf("validation error: InnerMessage.SomeFloat must be greater than or equal to '0'") + } + if !(this.SomeFloat <= 1) { + return fmt.Errorf("validation error: InnerMessage.SomeFloat must be less than or equal to '1'") + } + return nil +} + +var _regex_OuterMessage_ImportantString = regexp.MustCompile("^[a-z]{2,5}$") + +func (this *OuterMessage) Validate() error { + if !_regex_OuterMessage_ImportantString.MatchString(this.ImportantString) { + return fmt.Errorf("validation error: OuterMessage.ImportantString must conform to regex '^[a-z]{2,5}$'") + } + if nil == this.Inner { + return fmt.Errorf("validation error: OuterMessage.Inner message must exist") + } + if this.Inner != nil { + if err := validators.CallValidatorIfExists(this.Inner); err != nil { + return err + } + } + return nil +} +``` + +## Installing and using + +The `protoc` compiler expects to find plugins named `proto-gen-XYZ` on the execution `$PATH`. So first: + +```sh +export PATH=${PATH}:${GOPATH}/bin +``` + +Then, do the usual + +```sh +go get github.com/mwitkow/go-proto-validators/protoc-gen-govalidators +``` + +Your `protoc` builds probably look very simple like: + +```sh +protoc \ + --proto_path=. \ + --go_out=. \ + *.proto +``` + +That's fine, until you encounter `.proto` includes. Because `go-proto-validators` uses field options inside the `.proto` +files themselves, it's `.proto` definition (and the Google `descriptor.proto` itself) need to on the `protoc` include +path. Hence the above becomes: + +```sh +protoc \ + --proto_path=${GOPATH}/src \ + --proto_path=${GOPATH}/src/github.com/google/protobuf/src \ + --proto_path=. \ + --go_out=. \ + --govalidators_out=. \ + *.proto +``` + +Or with gogo protobufs: + +```sh +protoc \ + --proto_path=${GOPATH}/src \ + --proto_path=${GOPATH}/src/github.com/gogo/protobuf/protobuf \ + --proto_path=. \ + --gogo_out=. \ + --govalidators_out=gogoimport=true:. \ + *.proto +``` + +Basically the magical incantation (apart from includes) is the `--govalidators_out`. That triggers the +`protoc-gen-govalidators` plugin to generate `mymessage.validator.pb.go`. That's it :) + +## License + +`go-proto-validators` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details. |