最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go?gRPC服務(wù)proto數(shù)據(jù)驗(yàn)證進(jìn)階教程

 更新時(shí)間:2022年06月16日 09:47:58   作者:煙花易冷人憔悴  
這篇文章主要為大家介紹了Go?gRPC服務(wù)proto數(shù)據(jù)驗(yàn)證進(jìn)階教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

上篇介紹了go-grpc-middleware的grpc_zap、grpc_auth和grpc_recovery使用,本篇將介紹grpc_validator,它可以對(duì)gRPC數(shù)據(jù)的輸入和輸出進(jìn)行驗(yàn)證。

創(chuàng)建proto文件,添加驗(yàn)證規(guī)則

這里使用第三方插件go-proto-validators自動(dòng)生成驗(yàn)證規(guī)則。

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

1.新建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";包,不然會(huì)報(bào)錯(cuò)。

google/protobuf地址:

https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto

把src文件夾中的protobuf目錄下載到GOPATH目錄下。

2.編譯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",
        // 保存時(shí)自動(dòng)編譯
        "compile_on_save": true,
        "options": [
            // go編譯輸出指令
            "--go_out=plugins=grpc:.",
            "--govalidators_out=."
        ]
    },

編譯完成后,自動(dòng)生成simple.pb.go和simple.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.proto
package proto
import (
	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.Marshal
var _ = fmt.Errorf
var _ = math.Inf
func (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
}

里面自動(dòng)生成了message中屬性的驗(yàn)證規(guī)則。

把grpc_validator驗(yàn)證攔截器添加到服務(wù)端

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()),
		)),
	)

運(yùn)行后,當(dāng)輸入數(shù)據(jù)驗(yàn)證失敗后,會(huì)有以下錯(cuò)誤返回

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

其他類型驗(yàn)證規(guī)則設(shè)置

enum驗(yàn)證

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驗(yàn)證

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}];
}

總結(jié)

go-grpc-middleware中g(shù)rpc_validator集成go-proto-validators,我們只需要在編寫(xiě)proto時(shí)設(shè)好驗(yàn)證規(guī)則,并把grpc_validator添加到gRPC服務(wù)端,就能完成gRPC的數(shù)據(jù)驗(yàn)證,很簡(jiǎn)單也很方便。

教程源碼地址:https://github.com/Bingjian-Zhu/go-grpc-example

以上就是Go gRPC服務(wù)proto數(shù)據(jù)驗(yàn)證進(jìn)階教程的詳細(xì)內(nèi)容,更多關(guān)于Go gRPC服務(wù)proto數(shù)據(jù)驗(yàn)證的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • GO中對(duì)map排序的實(shí)現(xiàn)

    GO中對(duì)map排序的實(shí)現(xiàn)

    本文主要介紹了GO中對(duì)map排序的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 深度解密Go語(yǔ)言中字符串的使用

    深度解密Go語(yǔ)言中字符串的使用

    在編程語(yǔ)言中,字符串發(fā)揮著重要的角色。這篇文章就來(lái)帶大家一起深度解密Go語(yǔ)言中的字符串,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-09-09
  • Go語(yǔ)言實(shí)現(xiàn)二分查找方法示例

    Go語(yǔ)言實(shí)現(xiàn)二分查找方法示例

    這篇文章主要為大家介紹了Go語(yǔ)言實(shí)現(xiàn)二分查找方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • golang雙鏈表的實(shí)現(xiàn)代碼示例

    golang雙鏈表的實(shí)現(xiàn)代碼示例

    這篇文章主要介紹了golang雙鏈表的實(shí)現(xiàn)代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • golang數(shù)據(jù)結(jié)構(gòu)之golang稀疏數(shù)組sparsearray詳解

    golang數(shù)據(jù)結(jié)構(gòu)之golang稀疏數(shù)組sparsearray詳解

    這篇文章主要介紹了golang數(shù)據(jù)結(jié)構(gòu)之golang稀疏數(shù)組sparsearray的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Golang基于文件魔數(shù)判斷文件類型的案例代碼

    Golang基于文件魔數(shù)判斷文件類型的案例代碼

    這篇文章主要介紹了Golang基于文件魔數(shù)判斷文件類型,本文介紹了基于文件魔數(shù)判斷文件類型的方法,主要涉及如何ReadSeek讀取文件指定字節(jié)內(nèi)容,然后介紹文件魔數(shù),最后給出示例基于魔數(shù)判斷文件類型,需要的朋友可以參考下
    2023-02-02
  • Go可變參數(shù)函數(shù)的實(shí)現(xiàn)

    Go可變參數(shù)函數(shù)的實(shí)現(xiàn)

    可變參數(shù)函數(shù)是指函數(shù)參數(shù)的某個(gè)參數(shù)可有可無(wú),即這個(gè)參數(shù)的個(gè)數(shù)可以為0會(huì)多個(gè),可變參數(shù)函數(shù)參數(shù)在日常編程中大量使用,本文主要介紹了Go可變參數(shù)函數(shù)的實(shí)現(xiàn),感興趣的可以了解一下
    2023-12-12
  • Golang中crypto/cipher加密標(biāo)準(zhǔn)庫(kù)全面指南

    Golang中crypto/cipher加密標(biāo)準(zhǔn)庫(kù)全面指南

    本文主要介紹了Golang中crypto/cipher加密標(biāo)準(zhǔn)庫(kù),包括對(duì)稱加密、非對(duì)稱加密以及使用流加密和塊加密算法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • GO語(yǔ)言如何手動(dòng)處理TCP粘包詳解

    GO語(yǔ)言如何手動(dòng)處理TCP粘包詳解

    最近在用golang開(kāi)發(fā)人工客服系統(tǒng)的時(shí)候碰到了粘包問(wèn)題,那么什么是粘包呢?下面這篇文章就來(lái)給大家介紹了關(guān)于GO語(yǔ)言如何手動(dòng)處理TCP粘包的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒。
    2017-12-12
  • Golang服務(wù)的請(qǐng)求調(diào)度的實(shí)現(xiàn)

    Golang服務(wù)的請(qǐng)求調(diào)度的實(shí)現(xiàn)

    Golang服務(wù)請(qǐng)求調(diào)度是一種使用Go語(yǔ)言實(shí)現(xiàn)的服務(wù)請(qǐng)求管理方法,本文主要介紹了Golang服務(wù)的請(qǐng)求調(diào)度的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08

最新評(píng)論

深水埗区| 仁怀市| 融水| 九龙城区| 德保县| 新建县| 武冈市| 巢湖市| 黑龙江省| 宜君县| 富民县| 运城市| 珲春市| 太谷县| 丰镇市| 湖州市| 铜川市| 宜春市| 南华县| 澄江县| 阜南县| 福清市| 英超| 金堂县| 宣化县| 廊坊市| 安丘市| 巴南区| 外汇| 曲麻莱县| 甘孜县| 临泉县| 北票市| 三江| 祁连县| 丰县| 巴彦淖尔市| 无极县| 巍山| 华容县| 江西省|