gRPC验证器
文档
github.com/envoyproxy/protoc-gen-v...
安装
安装插件。
go install github.com/envoyproxy/protoc-gen-validate@latest
保存validate.proto文件
编写proto
syntax = "proto3";
package proto;
option go_package = "/test;test";
import "proto/validate.proto";
message RequestInfo {
uint64 id = 1 [(validate.rules).uint64.gt = 999];
string email = 2 [(validate.rules).string.email = true];
string name = 3 [(validate.rules).string = {
max_bytes: 256,
}];
}
message ResponseInfo {
string res = 1;
}
service Test {
rpc Test (RequestInfo) returns (ResponseInfo) {}
}
生成文件
通过 --validate_out
设置 validate
生成的路径。
因为 validate.proto
文件使用了 google
原生的类型,所以需要设置 google
原生的 proto
文件路径。
protoc -I D:\GoPath\pkg\mod\github.com\protocolbuffers\protobuf@v4.25.2+incompatible\src -I . --go_out=. --go-grpc_out=. --validate_out="lang=go:." ./proto/test.proto
代码中使用
在拦截器中使用 Validate
方法进行验证,具体请看下面代码。
服务端
package main
import (
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"net"
"strconv"
"test/test"
)
type Test struct {
test.UnimplementedTestServer
}
type Validator interface {
Validate() error
}
func (t *Test) Test(ctx context.Context, req *test.RequestInfo) (*test.ResponseInfo, error) {
return &test.ResponseInfo{Res: strconv.FormatUint(req.Id, 10)}, nil
}
func main() {
// 监听
listen, _ := net.Listen("tcp", ":8080")
// 设置拦截器
opt := grpc.UnaryInterceptor(func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
if r, ok := req.(Validator); ok {
// 进行验证
if err := r.Validate(); err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
}
res, err := handler(ctx, req)
return res, err
})
// 实例化grpc服务
s := grpc.NewServer(opt)
// 注册服务
test.RegisterTestServer(s, &Test{})
// 启动
s.Serve(listen)
}
客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"test/test"
)
func main() {
// 建立连接
conn, _ := grpc.Dial("127.0.0.1:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
// 实例化客户端
client := test.NewTestClient(conn)
res, err := client.Test(context.Background(), &test.RequestInfo{
Id: 999,
Name: "Protocol Buffer",
Email: "1231456@qq.com",
})
if err != nil {
fmt.Println(err)
} else {
fmt.Println(res.Res)
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接