Validate

Validate middleware uses proto-gen-validate generated code for parameter validation. You could write parameter validation rules in proto files and generate codes, in order to automatically parameter validation.

Installation

First you should install proto-gen-validate

  1. go install github.com/envoyproxy/protoc-gen-validate@latest

If any error appears in generation process or there are // no validation rules for xxxx in the generated codes, you could try git clone github.com/envoyproxy/protoc-gen-validate then run make build

Example

Here are some examples of parameter validation for several common situations, you may also refer to more examples in proto-gen-validate

Numerics

  1. // id must be greater than 0
  2. int64 id = 1 [(validate.rules).int64 = {gt: 0}];
  3. // age must be in the range (0, 120]
  4. int32 age = 2 [(validate.rules).int32 = {gt:0, lte: 120}];
  5. // code must be either 1, 2, or 3
  6. uint32 code = 3 [(validate.rules).uint32 = {in: [1,2,3]}];
  7. // score cannot be 0 nor 0.99
  8. float score = 1 [(validate.rules).float = {not_in: [0, 99.99]}];

Bools

  1. // state must be set to true
  2. bool state = 5 [(validate.rules).bool.const = true];
  3. // x cannot be set to true
  4. bool state = 5 [(validate.rules).bool.const = false];

Strings

  1. // x must be set to "/hello"
  2. string path = 6 [(validate.rules).string.const = "/hello"];
  3. // phone must be exactly 11 characters long
  4. string phone = 7 [(validate.rules).string.len = 11];
  5. // explain must be at least 10 characters long
  6. string explain = 8 [(validate.rules).string.min_len = 10];
  7. // name must be between 1 and 10 characters, inclusive
  8. string name = 9 [(validate.rules).string = {min_len: 1, max_len: 10}];
  9. // card must be a non-empty, case-insensitive hexadecimal string
  10. string card = 10 [(validate.rules).string.pattern = "(?i)^[0-9a-f]+$"];
  11. // x must be a valid email address (via RFC 1034)
  12. string email = 11 [(validate.rules).string.email = true];

Messages

  1. // info cannot be unset
  2. Info info = 11 [(validate.rules).message.required = true];
  3. message Info {
  4. string address = 1;
  5. }

Code Generation

1.Directly use the protoc command to generate

  1. protoc --proto_path=. \
  2. --proto_path=./third_party \
  3. --go_out=paths=source_relative:. \
  4. --validate_out=paths=source_relative,lang=go:. \
  5. xxxx.proto

2.Add the validate command in Makefile

  1. .PHONY: validate
  2. # generate validate proto
  3. validate:
  4. protoc --proto_path=. \
  5. --proto_path=./third_party \
  6. --go_out=paths=source_relative:. \
  7. --validate_out=paths=source_relative,lang=go:. \
  8. $(API_PROTO_FILES)

Execute command

  1. make validate

Middleware

We can inject the validate middleware into HTTP or gRPC, and the validate middleware automatically validates the parameters according to the rules written in the proto when request entering.

HTTP

  1. httpSrv := http.NewServer(
  2. http.Address(":8000"),
  3. http.Middleware(
  4. validate.Validator(),
  5. ))

gRPC

  1. grpcSrv := grpc.NewServer(
  2. grpc.Address(":9000"),
  3. grpc.Middleware(
  4. validate.Validator(),
  5. ))

References