GO语言proroc-gen-validate的使用
使用流程:
go get -u github.com/envoyproxy/protoc-gen-validate 下载windows .exe文件 https://oss.sonatype.org/content/repositories/snapshots/io/envoyproxy/protoc-gen-validate/protoc-gen-validate/0.6.3-SNAPSHOT/protoc-gen-validate-0.6.3-20211021.193822-1-windows-x86_64.exe github https://github.com/envoyproxy/protoc-gen-validate/blob/main/validate/validate.proto 复制 https://github.com/envoyproxy/protoc-gen-validate/blob/main/validate/validate.proto 文件里面的内容至本地 validate.proto protoc --go_out=plugins=grpc:. --validate_out="lang=go:." *.proto
protobuf定义:
syntax = "proto3"; option go_package = ".;proto"; import "validate.proto"; service Hello{ rpc Hello(Person) returns(Response); } message Person { uint64 id = 1 [(validate.rules).uint64.gt = 999]; string email = 2 [(validate.rules).string.email = true]; string mobile = 3 [(validate.rules).string = { pattern: "^1[3456789]\\d{9}$", }]; } message Response{ string data = 1; }
服务端代码:
重点1 type validate interface { Validate() error }
重点2 if r, ok := req.(validate); ok { if err := r.Validate(); err != nil { return resp, status.Error(codes.InvalidArgument, err.Error()) } }
package main import ( "context" "fmt" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "net" "rpc/validate_test/proto" ) type validate interface { Validate() error } type Server struct{} func (s Server) Hello(ctx context.Context, person *proto.Person) (*proto.Response, error) { return &proto.Response{ Data: person.Mobile, }, nil } func main() { listen, err := net.Listen("tcp", ":4321") if err != nil { fmt.Println("监听失败:", err) return } s := grpc.NewServer(grpc.UnaryInterceptor(func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { fmt.Println("有请求") if r, ok := req.(validate); ok { if err := r.Validate(); err != nil { return resp, status.Error(codes.InvalidArgument, err.Error()) } } return handler(ctx, req) })) proto.RegisterHelloServer(s, &Server{}) err = s.Serve(listen) if err != nil { fmt.Println("启动服务失败:", err) return } }
客户端代码:
package main import ( "fmt" "golang.org/x/net/context" "google.golang.org/grpc" "rpc/validate_test/proto" ) func main() { conn, err := grpc.Dial("localhost:4321", grpc.WithInsecure()) if err != nil { fmt.Println(err) return } defer conn.Close() cli := proto.NewHelloClient(conn) res, err := cli.Hello(context.Background(), &proto.Person{ Id: 1000, Email: "1272697385@qq.com", Mobile: "13163740715", }) if err != nil { fmt.Println(err) return } fmt.Println("服务器返回:", res.Data) }
发表评论