Preface
The previous article was introducedgo-grpc-middlewareThe use of grpc_zap, grpc_auth and grpc_recovery will introduce grpc_validator, which can verify the input and output of gRPC data.
Create a proto file and add verification rules
Use third-party plug-ins herego-proto-validatorsAutomatically generate verification rules.
go get /mwitkow/go-proto-validators
1. Create a new file
syntax = "proto3"; package proto; import "/mwitkow/go-proto-validators/"; message InnerMessage { // some_integer can only be in range (1, 100). int32 some_integer = 1 [() = {int_gt: 0, int_lt: 100}]; // some_float can only be in range (0;1). double some_float = 2 [() = {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 [() = {regex: "^[a-z]{2,5}$"}]; // proto3 doesn't have `required`, the `msg_exist` enforces presence of InnerMessage. InnerMessage inner = 2 [() = {msg_exists : true}]; } service Simple{ rpc Route (InnerMessage) returns (OuterMessage){}; }
The code imports "/mwitkow/go-proto-validators/", and the file needs to import "google/protobuf/"; package, otherwise an error will be reported.
google/protobuf address:
/protocolbuffers/protobuf/blob/main/src/google/protobuf/
Download the protobuf directory in the src folder to the GOPATH directory.
2. Compile the file
go get /mwitkow/go-proto-validators/protoc-gen-govalidators
Directive compilation:
protoc --govalidators_out=. --go_out=plugins=grpc:./ ./
Or use the VSCode-proto3 plugin,Article 1There is an introduction. Just add "--govalidators_out=."
// vscode-proto3 plugin configuration "protoc": { // Directory "path": "C:\\Go\\bin\\", // Automatically compile when saving "compile_on_save": true, "options": [ // go compile output command "--go_out=plugins=grpc:.", "--govalidators_out=." ] },
After the compilation is completed, the file and the file will be automatically generated and will not be introduced. Let’s look at the file.
// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: go-grpc-example/9-grpc_proto_validators/proto/ package proto import ( fmt "fmt" math "math" proto "/golang/protobuf/proto" _ "/mwitkow/go-proto-validators" regexp "regexp" github_com_mwitkow_go_proto_validators "/mwitkow/go-proto-validators" ) // Reference imports to suppress errors if they are not otherwise used. var _ = var _ = var _ = func (this *InnerMessage) Validate() error { if !( > 0) { return github_com_mwitkow_go_proto_validators.FieldError("SomeInteger", (`value '%v' must be greater than '0'`, )) } if !( < 100) { return github_com_mwitkow_go_proto_validators.FieldError("SomeInteger", (`value '%v' must be less than '100'`, )) } if !( >= 0) { return github_com_mwitkow_go_proto_validators.FieldError("SomeFloat", (`value '%v' must be greater than or equal to '0'`, )) } if !( <= 1) { return github_com_mwitkow_go_proto_validators.FieldError("SomeFloat", (`value '%v' must be lower than or equal to '1'`, )) } return nil } var _regex_OuterMessage_ImportantString = (`^[a-z]{2,5}$`) func (this *OuterMessage) Validate() error { if !_regex_OuterMessage_ImportantString.MatchString() { return github_com_mwitkow_go_proto_validators.FieldError("ImportantString", (`value '%v' must be a string conforming to regex "^[a-z]{2,5}$"`, )) } if nil == { return github_com_mwitkow_go_proto_validators.FieldError("Inner", ("message must exist")) } if != nil { if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(); err != nil { return github_com_mwitkow_go_proto_validators.FieldError("Inner", err) } } return nil }
The verification rules for the attributes in the message are automatically generated.
Add grpc_validator verification interceptor to the server
grpcServer := ((), (grpc_middleware.ChainStreamServer( grpc_validator.StreamServerInterceptor(), grpc_auth.StreamServerInterceptor(), grpc_zap.StreamServerInterceptor(()), grpc_recovery.StreamServerInterceptor(()), )), (grpc_middleware.ChainUnaryServer( grpc_validator.UnaryServerInterceptor(), grpc_auth.UnaryServerInterceptor(), grpc_zap.UnaryServerInterceptor(()), grpc_recovery.UnaryServerInterceptor(()), )), )
After running, when the input data verification fails, the following error will be returned.
Call Route err: rpc error: code = InvalidArgument desc = invalid field SomeInteger: value '101' must be less than '100'
Other types of verification rule settings
enum verification
syntax = "proto3"; package proto; import "/mwitkow/go-proto-validators/"; message SomeMsg { Action do = 1 [() = {is_in_enum : true}]; } enum Action { ALLOW = 0; DENY = 1; CHILL = 2; }
UUID Verification
syntax = "proto3"; package proto; import "/mwitkow/go-proto-validators/"; message UUIDMsg { // user_id must be a valid version 4 UUID. string user_id = 1 [() = {uuid_ver: 4, string_not_empty: true}]; }
Summarize
In go-grpc-middleware, grpc_validator integrates go-proto-validators. We only need to set up verification rules when writing proto and add grpc_validator to the gRPC server to complete gRPC data verification, which is very simple and convenient.
Tutorial source code address:/Bingjian-Zhu/go-grpc-example
The above is the detailed content of the advanced tutorial on Go gRPC service proto data verification. For more information about Go gRPC service proto data verification, please pay attention to my other related articles!