mirror of
https://github.com/chai2010/advanced-go-programming-book.git
synced 2025-05-29 08:12:21 +00:00
ch4: 完善
This commit is contained in:
parent
f98d1084f1
commit
cfe946b219
@ -314,7 +314,24 @@ func filter(
|
||||
}
|
||||
```
|
||||
|
||||
不够GRPC框架中只能为每个服务设置一个截取器,因此所有对截取工作只能在一个函数中完成。不过开源的grpc-ecosystem项目中的go-grpc-middleware包已经基于GRPC对截取器实现了链式截取器的支持,感兴趣的同学可以参考。
|
||||
不够GRPC框架中只能为每个服务设置一个截取器,因此所有对截取工作只能在一个函数中完成。开源的grpc-ecosystem项目中的go-grpc-middleware包已经基于GRPC对截取器实现了链式截取器的支持。
|
||||
|
||||
以下是go-grpc-middleware包中链式截取器的简单用法
|
||||
|
||||
```go
|
||||
import "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
|
||||
myServer := grpc.NewServer(
|
||||
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
|
||||
filter1, filter2, ...
|
||||
)),
|
||||
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
|
||||
filter1, filter2, ...
|
||||
)),
|
||||
)
|
||||
```
|
||||
|
||||
感兴趣的同学可以参考go-grpc-middleware包的代码。
|
||||
|
||||
## 和Web服务共存
|
||||
|
||||
|
@ -1,9 +1,157 @@
|
||||
# 4.6. GRPC扩展
|
||||
|
||||
<!--
|
||||
valiate
|
||||
gateway
|
||||
nginx
|
||||
-->
|
||||
目前开源社区已经围绕Protobuf和GRPC开发出众多扩展,形成了庞大的生态。本节我们将简单介绍验证器、REST接口和Nginx代理等几个比较流行的扩展。
|
||||
|
||||
## 验证器
|
||||
|
||||
到目前位置,我们接触的全部是第三版的Protobuf语法。第二版的Protobuf有个默认值特性,可以为字符串或数值类型的成员定义默认值。
|
||||
|
||||
我们采用第二版的Protobuf语法创建文件:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto2";
|
||||
|
||||
package main;
|
||||
|
||||
message Message {
|
||||
optional string name = 1 [default = "gopher"];
|
||||
optional int32 age = 2 [default = 10];
|
||||
}
|
||||
```
|
||||
|
||||
默认值语法内置其实是通过Protobuf的扩展选项特性实现。在第三版的Protobuf中不再支持默认值特性,但是我们可以通过扩展选项自己定制默认值。
|
||||
|
||||
下面是用proto3语法的扩展特性重新改写上述的proto文件:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto3";
|
||||
|
||||
package main;
|
||||
|
||||
import "google/protobuf/descriptor.proto";
|
||||
|
||||
extend google.protobuf.FieldOptions {
|
||||
string default_string = 50000;
|
||||
int32 default_int = 50001;
|
||||
}
|
||||
|
||||
message Message {
|
||||
string name = 1 [(default_string) = "gopher"];
|
||||
int32 age = 2[(default_int) = 10];
|
||||
}
|
||||
```
|
||||
|
||||
其中成员后面的方括号内部的就是扩展语法。重新生成Go语言代码,里面会包含扩展选项相关的元信息:
|
||||
|
||||
```go
|
||||
var E_DefaultString = &proto.ExtensionDesc{
|
||||
ExtendedType: (*descriptor.FieldOptions)(nil),
|
||||
ExtensionType: (*string)(nil),
|
||||
Field: 50000,
|
||||
Name: "main.default_string",
|
||||
Tag: "bytes,50000,opt,name=default_string,json=defaultString",
|
||||
Filename: "helloworld.proto",
|
||||
}
|
||||
|
||||
var E_DefaultInt = &proto.ExtensionDesc{
|
||||
ExtendedType: (*descriptor.FieldOptions)(nil),
|
||||
ExtensionType: (*int32)(nil),
|
||||
Field: 50001,
|
||||
Name: "main.default_int",
|
||||
Tag: "varint,50001,opt,name=default_int,json=defaultInt",
|
||||
Filename: "helloworld.proto",
|
||||
}
|
||||
```
|
||||
|
||||
我们可以在运行时通过类似反射的技术解析出Message每个成员定义的扩展选项,然后从每个扩展的相关联的信息中解析出我们定义的默认值。
|
||||
|
||||
在开源社区中,github.com/mwitkow/go-proto-validators 基于Protobuf的扩展特性实现了功能较为强大的验证器功能。要使用该验证器首先需要下载其提供的代码生成插件:
|
||||
|
||||
```
|
||||
$ go get github.com/mwitkow/go-proto-validators/protoc-gen-govalidators
|
||||
```
|
||||
|
||||
然后基于go-proto-validators验证器重新定义上述的Message成员的验证规则:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto3";
|
||||
|
||||
package main;
|
||||
|
||||
import "github.com/mwitkow/go-proto-validators/validator.proto";
|
||||
|
||||
message Message {
|
||||
string important_string = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}];
|
||||
int32 age = 2 [(validator.field) = {int_gt: 0, int_lt: 100}];
|
||||
}
|
||||
```
|
||||
|
||||
在方括弧表示的成员扩展中,validator.field表示扩展是validator包中定义的名为field扩展选项。validator.field的类型是FieldValidator结构体,在导入的validator.proto文件中定义。
|
||||
|
||||
validator.proto文件的内容如下:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto2";
|
||||
package validator;
|
||||
|
||||
import "google/protobuf/descriptor.proto";
|
||||
|
||||
extend google.protobuf.FieldOptions {
|
||||
optional FieldValidator field = 65020;
|
||||
}
|
||||
|
||||
message FieldValidator {
|
||||
// Uses a Golang RE2-syntax regex to match the field contents.
|
||||
optional string regex = 1;
|
||||
// Field value of integer strictly greater than this value.
|
||||
optional int64 int_gt = 2;
|
||||
// Field value of integer strictly smaller than this value.
|
||||
optional int64 int_lt = 3;
|
||||
|
||||
// ... more ...
|
||||
}
|
||||
```
|
||||
|
||||
从FieldValidator定义的注释中我们可以知道验证器扩展的一些语法:其中regex表示用于字符串验证的正则表达式,int_gt和int_lt表示数值的范围。
|
||||
|
||||
采用以下的命令生成验证函数代码:
|
||||
|
||||
```
|
||||
protoc \
|
||||
--proto_path=${GOPATH}/src \
|
||||
--proto_path=${GOPATH}/src/github.com/google/protobuf/src \
|
||||
--proto_path=. \
|
||||
--govalidators_out=. \
|
||||
hello.proto
|
||||
```
|
||||
|
||||
以上的命令会调用protoc-gen-govalidators程序,生成一个名为hello.validator.pb.go的代码:
|
||||
|
||||
```go
|
||||
var _regex_Message_ImportantString = regexp.MustCompile("^[a-z]{2,5}$")
|
||||
|
||||
func (this *Message) Validate() error {
|
||||
if !_regex_Message_ImportantString.MatchString(this.ImportantString) {
|
||||
return go_proto_validators.FieldError("ImportantString", fmt.Errorf(`value '%v' must be a string conforming to regex "^[a-z]{2,5}$"`, this.ImportantString))
|
||||
}
|
||||
if !(this.Age > 0) {
|
||||
return go_proto_validators.FieldError("Age", fmt.Errorf(`value '%v' must be greater than '0'`, this.Age))
|
||||
}
|
||||
if !(this.Age < 100) {
|
||||
return go_proto_validators.FieldError("Age", fmt.Errorf(`value '%v' must be less than '100'`, this.Age))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
也就是为Message结构体增加了一个Validate方法,用于验证该成员是否满足Protobuf中定义的条件约束。
|
||||
|
||||
通过生成的验证函数,并结合GRPC的截取器,我们可以很容易为每个方法的输入参数和返回值进行验证。
|
||||
|
||||
## REST接口
|
||||
|
||||
TODO
|
||||
|
||||
## Nginx代理
|
||||
|
||||
TODO
|
||||
|
10
vendor/gobook.examples/ch4-06-grpc-ext/pb2-default-value/Makefile
vendored
Normal file
10
vendor/gobook.examples/ch4-06-grpc-ext/pb2-default-value/Makefile
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
run:
|
||||
@go build -o a.out && ./a.out
|
||||
-@rm ./a.out
|
||||
|
||||
gen:
|
||||
protoc -I . --go_out=plugins=grpc:. helloworld.proto
|
||||
|
||||
clean:
|
||||
-rm *.pb.go
|
110
vendor/gobook.examples/ch4-06-grpc-ext/pb2-default-value/helloworld.pb.go
vendored
Normal file
110
vendor/gobook.examples/ch4-06-grpc-ext/pb2-default-value/helloworld.pb.go
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: helloworld.proto
|
||||
|
||||
package main
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type Message struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Message) Reset() { *m = Message{} }
|
||||
func (m *Message) String() string { return proto.CompactTextString(m) }
|
||||
func (*Message) ProtoMessage() {}
|
||||
func (*Message) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_helloworld_0196a2ef510324e3, []int{0}
|
||||
}
|
||||
func (m *Message) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Message.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Message.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Message) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Message.Merge(dst, src)
|
||||
}
|
||||
func (m *Message) XXX_Size() int {
|
||||
return xxx_messageInfo_Message.Size(m)
|
||||
}
|
||||
func (m *Message) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Message.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Message proto.InternalMessageInfo
|
||||
|
||||
func (m *Message) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Message) GetAge() int32 {
|
||||
if m != nil {
|
||||
return m.Age
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var E_DefaultString = &proto.ExtensionDesc{
|
||||
ExtendedType: (*descriptor.FieldOptions)(nil),
|
||||
ExtensionType: (*string)(nil),
|
||||
Field: 50000,
|
||||
Name: "main.default_string",
|
||||
Tag: "bytes,50000,opt,name=default_string,json=defaultString",
|
||||
Filename: "helloworld.proto",
|
||||
}
|
||||
|
||||
var E_DefaultInt = &proto.ExtensionDesc{
|
||||
ExtendedType: (*descriptor.FieldOptions)(nil),
|
||||
ExtensionType: (*int32)(nil),
|
||||
Field: 50001,
|
||||
Name: "main.default_int",
|
||||
Tag: "varint,50001,opt,name=default_int,json=defaultInt",
|
||||
Filename: "helloworld.proto",
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Message)(nil), "main.Message")
|
||||
proto.RegisterExtension(E_DefaultString)
|
||||
proto.RegisterExtension(E_DefaultInt)
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("helloworld.proto", fileDescriptor_helloworld_0196a2ef510324e3) }
|
||||
|
||||
var fileDescriptor_helloworld_0196a2ef510324e3 = []byte{
|
||||
// 217 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9,
|
||||
0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d,
|
||||
0xcc, 0xcc, 0x93, 0x52, 0x48, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x07, 0x8b, 0x25, 0x95, 0xa6,
|
||||
0xe9, 0xa7, 0xa4, 0x16, 0x27, 0x17, 0x65, 0x16, 0x94, 0xe4, 0x17, 0x41, 0xd4, 0x29, 0x39, 0x72,
|
||||
0xb1, 0xfb, 0xa6, 0x16, 0x17, 0x27, 0xa6, 0xa7, 0x0a, 0xc9, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6,
|
||||
0x4a, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x3a, 0x71, 0x35, 0x6d, 0x95, 0x60, 0x4b, 0xcf, 0x2f, 0xc8,
|
||||
0x48, 0x2d, 0x0a, 0x02, 0x8b, 0x0b, 0x89, 0x71, 0x31, 0x27, 0xa6, 0xa7, 0x4a, 0x30, 0x29, 0x30,
|
||||
0x6a, 0xb0, 0x3a, 0xb1, 0x74, 0x6c, 0x95, 0xe0, 0x0a, 0x02, 0x09, 0x58, 0xb9, 0x71, 0xf1, 0xa5,
|
||||
0xa4, 0xa6, 0x25, 0x96, 0xe6, 0x94, 0xc4, 0x17, 0x97, 0x14, 0x65, 0xe6, 0xa5, 0x0b, 0xc9, 0xea,
|
||||
0x41, 0xec, 0xd5, 0x83, 0xd9, 0xab, 0xe7, 0x96, 0x99, 0x9a, 0x93, 0xe2, 0x5f, 0x50, 0x92, 0x99,
|
||||
0x9f, 0x57, 0x2c, 0x71, 0xa1, 0x8d, 0x19, 0x64, 0x45, 0x10, 0x2f, 0x54, 0x5b, 0x30, 0x58, 0x97,
|
||||
0x95, 0x03, 0x17, 0x37, 0xcc, 0x9c, 0xcc, 0xbc, 0x12, 0x42, 0x86, 0x5c, 0x04, 0x1b, 0xc2, 0x1a,
|
||||
0xc4, 0x05, 0xd5, 0xe3, 0x99, 0x57, 0x92, 0xc4, 0x06, 0x56, 0x6a, 0x0c, 0x08, 0x00, 0x00, 0xff,
|
||||
0xff, 0xce, 0x8c, 0x0b, 0x48, 0x0f, 0x01, 0x00, 0x00,
|
||||
}
|
15
vendor/gobook.examples/ch4-06-grpc-ext/pb2-default-value/helloworld.proto
vendored
Normal file
15
vendor/gobook.examples/ch4-06-grpc-ext/pb2-default-value/helloworld.proto
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package main;
|
||||
|
||||
import "google/protobuf/descriptor.proto";
|
||||
|
||||
extend google.protobuf.FieldOptions {
|
||||
string default_string = 50000;
|
||||
int32 default_int = 50001;
|
||||
}
|
||||
|
||||
message Message {
|
||||
string name = 1 [(default_string) = "gopher"];
|
||||
int32 age = 2[(default_int) = 10];
|
||||
}
|
14
vendor/gobook.examples/ch4-06-grpc-ext/validators/Makefile
vendored
Normal file
14
vendor/gobook.examples/ch4-06-grpc-ext/validators/Makefile
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
run:
|
||||
@go build -o a.out && ./a.out
|
||||
-@rm ./a.out
|
||||
|
||||
aa:
|
||||
cd ../../.. && pwd
|
||||
|
||||
gen:
|
||||
protoc -I=. -I=../../.. --go_out=plugins=grpc:. helloworld.proto
|
||||
protoc -I=. -I=../../.. --govalidators_out=. helloworld.proto
|
||||
|
||||
clean:
|
||||
-rm *.pb.go
|
88
vendor/gobook.examples/ch4-06-grpc-ext/validators/helloworld.pb.go
vendored
Normal file
88
vendor/gobook.examples/ch4-06-grpc-ext/validators/helloworld.pb.go
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: helloworld.proto
|
||||
|
||||
package main
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import _ "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
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type Message struct {
|
||||
ImportantString string `protobuf:"bytes,1,opt,name=important_string,json=importantString,proto3" json:"important_string,omitempty"`
|
||||
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Message) Reset() { *m = Message{} }
|
||||
func (m *Message) String() string { return proto.CompactTextString(m) }
|
||||
func (*Message) ProtoMessage() {}
|
||||
func (*Message) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_helloworld_6a5a39a6dbe7620e, []int{0}
|
||||
}
|
||||
func (m *Message) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Message.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Message.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Message) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Message.Merge(dst, src)
|
||||
}
|
||||
func (m *Message) XXX_Size() int {
|
||||
return xxx_messageInfo_Message.Size(m)
|
||||
}
|
||||
func (m *Message) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Message.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Message proto.InternalMessageInfo
|
||||
|
||||
func (m *Message) GetImportantString() string {
|
||||
if m != nil {
|
||||
return m.ImportantString
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Message) GetAge() int32 {
|
||||
if m != nil {
|
||||
return m.Age
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Message)(nil), "main.Message")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("helloworld.proto", fileDescriptor_helloworld_6a5a39a6dbe7620e) }
|
||||
|
||||
var fileDescriptor_helloworld_6a5a39a6dbe7620e = []byte{
|
||||
// 185 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9,
|
||||
0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d,
|
||||
0xcc, 0xcc, 0x93, 0x32, 0x4b, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf,
|
||||
0x2d, 0xcf, 0x2c, 0xc9, 0xce, 0x2f, 0xd7, 0x4f, 0xcf, 0xd7, 0x05, 0x2b, 0xd1, 0x2d, 0x4b, 0xcc,
|
||||
0xc9, 0x4c, 0x49, 0x2c, 0xc9, 0x2f, 0x2a, 0xd6, 0x87, 0x33, 0x21, 0xba, 0x95, 0x52, 0xb8, 0xd8,
|
||||
0x7d, 0x53, 0x8b, 0x8b, 0x13, 0xd3, 0x53, 0x85, 0x6c, 0xb9, 0x04, 0x32, 0x73, 0x0b, 0xf2, 0x8b,
|
||||
0x4a, 0x12, 0xf3, 0x4a, 0xe2, 0x8b, 0x4b, 0x8a, 0x32, 0xf3, 0xd2, 0x25, 0x18, 0x15, 0x18, 0x35,
|
||||
0x38, 0x9d, 0x84, 0x1e, 0xdd, 0x97, 0xe7, 0xe3, 0xe2, 0x89, 0x8b, 0x4e, 0xd4, 0xad, 0x8a, 0xad,
|
||||
0x36, 0xd2, 0x31, 0xad, 0x55, 0x09, 0xe2, 0x87, 0xab, 0x0d, 0x06, 0x2b, 0x15, 0x92, 0xe2, 0x62,
|
||||
0x4e, 0x4c, 0x4f, 0x95, 0x60, 0x52, 0x60, 0xd4, 0x60, 0x75, 0xe2, 0x78, 0x74, 0x5f, 0x9e, 0x45,
|
||||
0x80, 0x41, 0x22, 0x25, 0x08, 0x24, 0x98, 0xc4, 0x06, 0xb6, 0xcc, 0x18, 0x10, 0x00, 0x00, 0xff,
|
||||
0xff, 0xa7, 0x15, 0x2e, 0x91, 0xbe, 0x00, 0x00, 0x00,
|
||||
}
|
10
vendor/gobook.examples/ch4-06-grpc-ext/validators/helloworld.proto
vendored
Normal file
10
vendor/gobook.examples/ch4-06-grpc-ext/validators/helloworld.proto
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package main;
|
||||
|
||||
import "github.com/mwitkow/go-proto-validators/validator.proto";
|
||||
|
||||
message Message {
|
||||
string important_string = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}];
|
||||
int32 age = 2 [(validator.field) = {int_gt: 0, int_lt: 100}];
|
||||
}
|
40
vendor/gobook.examples/ch4-06-grpc-ext/validators/helloworld.validator.pb.go
vendored
Normal file
40
vendor/gobook.examples/ch4-06-grpc-ext/validators/helloworld.validator.pb.go
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: helloworld.proto
|
||||
|
||||
/*
|
||||
Package main is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
helloworld.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Message
|
||||
*/
|
||||
package main
|
||||
|
||||
import regexp "regexp"
|
||||
import fmt "fmt"
|
||||
import go_proto_validators "github.com/mwitkow/go-proto-validators"
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import math "math"
|
||||
import _ "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
|
||||
|
||||
var _regex_Message_ImportantString = regexp.MustCompile("^[a-z]{2,5}$")
|
||||
|
||||
func (this *Message) Validate() error {
|
||||
if !_regex_Message_ImportantString.MatchString(this.ImportantString) {
|
||||
return go_proto_validators.FieldError("ImportantString", fmt.Errorf(`value '%v' must be a string conforming to regex "^[a-z]{2,5}$"`, this.ImportantString))
|
||||
}
|
||||
if !(this.Age > 0) {
|
||||
return go_proto_validators.FieldError("Age", fmt.Errorf(`value '%v' must be greater than '0'`, this.Age))
|
||||
}
|
||||
if !(this.Age < 100) {
|
||||
return go_proto_validators.FieldError("Age", fmt.Errorf(`value '%v' must be less than '100'`, this.Age))
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user