* Adding a way to inject a request ID It is very useful to associate a request ID to each incoming request, this change allows to provide a function to do that via Server Option. The change comes with a default function which will generate a new request ID. The request ID is put in the request context along with a common logger which always logs the request-id We add gRPC interceptors to the server so it can get the request ID out of the gRPC metadata and put it in the common logger stored in the context so as all the log lines using the common logger from the context will have the request ID logged
grpc_validator
import "github.com/grpc-ecosystem/go-grpc-middleware/validator"
grpc_validator is a generic request contents validator server-side middleware for
gRPC.
Request Validator Middleware
Validating input is important, and hard. It also causes a lot of boilerplate code.
This middleware checks for the existence of a Validate method on each of the
messages of a gRPC request. This includes the single request of the Unary
calls, as well as each message of the inbound Stream calls. In case of a
validation failure, an InvalidArgument gRPC status is returned, along with
a description of the validation failure.
While it is generic, it was intended to be used with
https://github.com/mwitkow/go-proto-validators, a Go protocol buffers codegen
plugin that creates the Validate methods (including nested messages) based on
declarative options in the .proto files themselves. For example:
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}];
}
The OuterMessage.Validate would include validation of regexes, existence of
the InnerMessage and the range values within it. The grpc_validator middleware
would then automatically use that to check all messages processed by the server.
Please consult https://github.com/mwitkow/go-proto-validators for details on
protoc invocation and other parameters of customization.
Usage
func StreamServerInterceptor
func StreamServerInterceptor() grpc.StreamServerInterceptor
StreamServerInterceptor returns a new streaming server interceptor that validates incoming messages.
The stage at which invalid messages will be rejected with InvalidArgument
varies based on the type of the RPC. For ServerStream (1:m) requests, it will
happen before reaching any userspace handlers. For ClientStream (n:1) or
BidiStream (n:m) RPCs, the messages will be rejected on calls to
stream.Recv().
func UnaryServerInterceptor
func UnaryServerInterceptor() grpc.UnaryServerInterceptor
UnaryServerInterceptor returns a new unary server interceptor that validates incoming messages.
Invalid messages will be rejected with InvalidArgument before reaching any
userspace handlers.