一、简介
protobuf 可以通过插件实现请求参数的校验,并通过自定义middleware实现参数自动校验。
二、使用教程
2.1 安装插件
go get github.com/envoyproxy/protoc-gen-validate@v0.1.0
go install github.com/envoyproxy/protoc-gen-validate@v0.1.0
2.2 proto 文件定义
syntax = "proto3";
import "google/api/annotations.proto";
import "validate/validate.proto";
package main;
option go_package = "/main;student";
message Student {
string name = 1 [(validate.rules).string={
pattern: "\\w+",
min_len: 5
}];
int32 age = 2;
repeated int32 scores = 3;
}
service StudentService {
rpc GetStudent(Student) returns (Student){
option (google.api.http) = {
post: "/v1/student/get"
body: "*"
};
};
}
2.3 protoc 插件编译
protoc --proto_path=./third_party --proto_path=. --go_out=. --go-grpc_out=. --go_opt=paths=source_relative --validate_out=paths=source_relative,lang=go:./main student.proto
2.4 使用demo
func main() {
s := &student.Student{
Age: 18,
Name: "tom",
}
err := s.Validate()
if err != nil {
panic(err)
return
}
}
2.5 自定义grpc handler
type validator interface {
Validate() error
}
func Validator() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
if v, ok := req.(validator); ok {
if err := v.Validate(); err != nil {
// 参数验证失败,返回错误
return nil, err
}
}
return handler(ctx, req)
}
}