文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Go gRPC服务proto数据验证怎么实现

2023-07-02 10:07

关注

今天小编给大家分享一下Go gRPC服务proto数据验证怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

创建proto文件,添加验证规则

这里使用第三方插件go-proto-validators自动生成验证规则。

go get github.com/mwitkow/go-proto-validators

新建simple.proto文件

syntax = "proto3";package proto;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}];}service Simple{  rpc Route (InnerMessage) returns (OuterMessage){};}

代码import "github.com/mwitkow/go-proto-validators/validator.proto",文件validator.proto需要import "google/protobuf/descriptor.proto";包,不然会报错。

src文件夹中的protobuf目录下载到GOPATH目录下。

编译simple.proto文件

go get github.com/mwitkow/go-proto-validators/protoc-gen-govalidators

指令编译:

protoc --govalidators_out=. --go_out=plugins=grpc:./ ./simple.proto

或者使用VSCode-proto3插件,第一篇有介绍。只需要添加"--govalidators_out=."即可。

    // vscode-proto3插件配置    "protoc": {        // protoc.exe所在目录        "path": "C:\\Go\\bin\\protoc.exe",        // 保存时自动编译        "compile_on_save": true,        "options": [            // go编译输出指令            "--go_out=plugins=grpc:.",            "--govalidators_out=."        ]    },

编译完成后,自动生成simple.pb.gosimple.validator.pb.go文件,simple.pb.go文件不再介绍,我们看下simple.validator.pb.go文件。

// Code generated by protoc-gen-gogo. DO NOT EDIT.// source: go-grpc-example/9-grpc_proto_validators/proto/simple.protopackage protoimport (fmt "fmt"math "math"proto "github.com/golang/protobuf/proto"_ "github.com/mwitkow/go-proto-validators"regexp "regexp"github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators")// Reference imports to suppress errors if they are not otherwise used.var _ = proto.Marshalvar _ = fmt.Errorfvar _ = math.Inffunc (this *InnerMessage) Validate() error {if !(this.SomeInteger > 0) {return github_com_mwitkow_go_proto_validators.FieldError("SomeInteger", fmt.Errorf(`value '%v' must be greater than '0'`, this.SomeInteger))}if !(this.SomeInteger < 100) {return github_com_mwitkow_go_proto_validators.FieldError("SomeInteger", fmt.Errorf(`value '%v' must be less than '100'`, this.SomeInteger))}if !(this.SomeFloat >= 0) {return github_com_mwitkow_go_proto_validators.FieldError("SomeFloat", fmt.Errorf(`value '%v' must be greater than or equal to '0'`, this.SomeFloat))}if !(this.SomeFloat <= 1) {return github_com_mwitkow_go_proto_validators.FieldError("SomeFloat", fmt.Errorf(`value '%v' must be lower than or equal to '1'`, this.SomeFloat))}return nil}var _regex_OuterMessage_ImportantString = regexp.MustCompile(`^[a-z]{2,5}$`)func (this *OuterMessage) Validate() error {if !_regex_OuterMessage_ImportantString.MatchString(this.ImportantString) {return github_com_mwitkow_go_proto_validators.FieldError("ImportantString", fmt.Errorf(`value '%v' must be a string conforming to regex "^[a-z]{2,5}$"`, this.ImportantString))}if nil == this.Inner {return github_com_mwitkow_go_proto_validators.FieldError("Inner", fmt.Errorf("message must exist"))}if this.Inner != nil {if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Inner); err != nil {return github_com_mwitkow_go_proto_validators.FieldError("Inner", err)}}return nil}

里面自动生成了message中属性的验证规则。

grpc_validator验证拦截器添加到服务端

grpcServer := grpc.NewServer(cred.TLSInterceptor(),grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(grpc_validator.StreamServerInterceptor(),        grpc_auth.StreamServerInterceptor(auth.AuthInterceptor),grpc_zap.StreamServerInterceptor(zap.ZapInterceptor()),grpc_recovery.StreamServerInterceptor(recovery.RecoveryInterceptor()),)),grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(    grpc_validator.UnaryServerInterceptor(),    grpc_auth.UnaryServerInterceptor(auth.AuthInterceptor),grpc_zap.UnaryServerInterceptor(zap.ZapInterceptor()),            grpc_recovery.UnaryServerInterceptor(recovery.RecoveryInterceptor()),)),)

运行后,当输入数据验证失败后,会有以下错误返回

Call Route err: rpc error: code = InvalidArgument desc = invalid field SomeInteger: value '101' must be less than '100'

其他类型验证规则设置

enum验证

syntax = "proto3";package proto;import "github.com/mwitkow/go-proto-validators/validator.proto";message SomeMsg {  Action do = 1 [(validator.field) = {is_in_enum : true}];}enum Action {  ALLOW = 0;  DENY = 1;  CHILL = 2;}

UUID验证

syntax = "proto3";package proto;import "github.com/mwitkow/go-proto-validators/validator.proto";message UUIDMsg {  // user_id must be a valid version 4 UUID.  string user_id = 1 [(validator.field) = {uuid_ver: 4, string_not_empty: true}];}

以上就是“Go gRPC服务proto数据验证怎么实现”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯