add examples/validate (#1093)

pull/1094/head
包子 3 years ago committed by GitHub
parent b6fc811744
commit 6dc8300ee8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 387
      examples/validate/api/example.pb.go
  2. 493
      examples/validate/api/example.pb.validate.go
  3. 43
      examples/validate/api/example.proto
  4. 101
      examples/validate/api/example_grpc.pb.go
  5. 69
      examples/validate/api/example_http.pb.go
  6. 55
      examples/validate/main.go

@ -0,0 +1,387 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.13.0
// source: example.proto
package v1
import (
_ "github.com/envoyproxy/protoc-gen-validate/validate"
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Reply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *Reply) Reset() {
*x = Reply{}
if protoimpl.UnsafeEnabled {
mi := &file_example_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Reply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Reply) ProtoMessage() {}
func (x *Reply) ProtoReflect() protoreflect.Message {
mi := &file_example_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Reply.ProtoReflect.Descriptor instead.
func (*Reply) Descriptor() ([]byte, []int) {
return file_example_proto_rawDescGZIP(), []int{0}
}
func (x *Reply) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
type Request struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
Code uint32 `protobuf:"varint,3,opt,name=code,proto3" json:"code,omitempty"`
Score float32 `protobuf:"fixed32,4,opt,name=score,proto3" json:"score,omitempty"`
State bool `protobuf:"varint,5,opt,name=state,proto3" json:"state,omitempty"`
Path string `protobuf:"bytes,6,opt,name=path,proto3" json:"path,omitempty"`
Phone string `protobuf:"bytes,7,opt,name=phone,proto3" json:"phone,omitempty"`
Explain string `protobuf:"bytes,8,opt,name=explain,proto3" json:"explain,omitempty"`
Name string `protobuf:"bytes,9,opt,name=name,proto3" json:"name,omitempty"`
Card string `protobuf:"bytes,10,opt,name=card,proto3" json:"card,omitempty"`
Info *Info `protobuf:"bytes,11,opt,name=info,proto3" json:"info,omitempty"`
}
func (x *Request) Reset() {
*x = Request{}
if protoimpl.UnsafeEnabled {
mi := &file_example_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Request) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Request) ProtoMessage() {}
func (x *Request) ProtoReflect() protoreflect.Message {
mi := &file_example_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Request.ProtoReflect.Descriptor instead.
func (*Request) Descriptor() ([]byte, []int) {
return file_example_proto_rawDescGZIP(), []int{1}
}
func (x *Request) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
func (x *Request) GetAge() int32 {
if x != nil {
return x.Age
}
return 0
}
func (x *Request) GetCode() uint32 {
if x != nil {
return x.Code
}
return 0
}
func (x *Request) GetScore() float32 {
if x != nil {
return x.Score
}
return 0
}
func (x *Request) GetState() bool {
if x != nil {
return x.State
}
return false
}
func (x *Request) GetPath() string {
if x != nil {
return x.Path
}
return ""
}
func (x *Request) GetPhone() string {
if x != nil {
return x.Phone
}
return ""
}
func (x *Request) GetExplain() string {
if x != nil {
return x.Explain
}
return ""
}
func (x *Request) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Request) GetCard() string {
if x != nil {
return x.Card
}
return ""
}
func (x *Request) GetInfo() *Info {
if x != nil {
return x.Info
}
return nil
}
type Info struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
}
func (x *Info) Reset() {
*x = Info{}
if protoimpl.UnsafeEnabled {
mi := &file_example_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Info) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Info) ProtoMessage() {}
func (x *Info) ProtoReflect() protoreflect.Message {
mi := &file_example_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Info.ProtoReflect.Descriptor instead.
func (*Info) Descriptor() ([]byte, []int) {
return file_example_proto_rawDescGZIP(), []int{2}
}
func (x *Info) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
var File_example_proto protoreflect.FileDescriptor
var file_example_proto_rawDesc = []byte{
0x0a, 0x0d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x0b, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x1a, 0x1c, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x21, 0x0a, 0x05, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07,
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x88, 0x03, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07,
0xfa, 0x42, 0x04, 0x22, 0x02, 0x20, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x61,
0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x1a, 0x04, 0x10,
0x78, 0x20, 0x00, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x2a, 0x06, 0x30, 0x01, 0x30,
0x02, 0x30, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x63, 0x6f,
0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x42, 0x0f, 0xfa, 0x42, 0x0c, 0x0a, 0x0a, 0x3d,
0x00, 0x00, 0x00, 0x00, 0x3d, 0xe1, 0xfa, 0xc7, 0x42, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65,
0x12, 0x1d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x42,
0x07, 0xfa, 0x42, 0x04, 0x6a, 0x02, 0x08, 0x01, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12,
0x21, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xfa,
0x42, 0x0a, 0x72, 0x08, 0x0a, 0x06, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x04, 0x70, 0x61,
0x74, 0x68, 0x12, 0x1e, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28,
0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x98, 0x01, 0x0b, 0x52, 0x05, 0x70, 0x68, 0x6f,
0x6e, 0x65, 0x12, 0x21, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x18, 0x08, 0x20,
0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x03, 0x52, 0x07, 0x65, 0x78,
0x70, 0x6c, 0x61, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20,
0x01, 0x28, 0x09, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x72, 0x04, 0x10, 0x01, 0x18, 0x0a, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x63, 0x61, 0x72, 0x64, 0x18, 0x0a, 0x20, 0x01,
0x28, 0x09, 0x42, 0x16, 0xfa, 0x42, 0x13, 0x72, 0x11, 0x32, 0x0f, 0x28, 0x3f, 0x69, 0x29, 0x5e,
0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x5d, 0x2b, 0x24, 0x52, 0x04, 0x63, 0x61, 0x72, 0x64,
0x12, 0x2f, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x49, 0x6e, 0x66,
0x6f, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x04, 0x69, 0x6e, 0x66,
0x6f, 0x22, 0x20, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x32, 0x64, 0x0a, 0x0e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x78, 0x61, 0x6d,
0x70, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22,
0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x22, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x3a, 0x01, 0x2a, 0x42, 0x4c, 0x0a, 0x0f, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x50, 0x00, 0x5a, 0x37,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72,
0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d,
0x70, 0x6c, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_example_proto_rawDescOnce sync.Once
file_example_proto_rawDescData = file_example_proto_rawDesc
)
func file_example_proto_rawDescGZIP() []byte {
file_example_proto_rawDescOnce.Do(func() {
file_example_proto_rawDescData = protoimpl.X.CompressGZIP(file_example_proto_rawDescData)
})
return file_example_proto_rawDescData
}
var file_example_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_example_proto_goTypes = []interface{}{
(*Reply)(nil), // 0: api.example.Reply
(*Request)(nil), // 1: api.example.Request
(*Info)(nil), // 2: api.example.Info
}
var file_example_proto_depIdxs = []int32{
2, // 0: api.example.Request.info:type_name -> api.example.Info
1, // 1: api.example.ExampleService.TestValidate:input_type -> api.example.Request
0, // 2: api.example.ExampleService.TestValidate:output_type -> api.example.Reply
2, // [2:3] is the sub-list for method output_type
1, // [1:2] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_example_proto_init() }
func file_example_proto_init() {
if File_example_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_example_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Reply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_example_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Request); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_example_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Info); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_example_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_example_proto_goTypes,
DependencyIndexes: file_example_proto_depIdxs,
MessageInfos: file_example_proto_msgTypes,
}.Build()
File_example_proto = out.File
file_example_proto_rawDesc = nil
file_example_proto_goTypes = nil
file_example_proto_depIdxs = nil
}

@ -0,0 +1,493 @@
// Code generated by protoc-gen-validate. DO NOT EDIT.
// source: example.proto
package v1
import (
"bytes"
"errors"
"fmt"
"net"
"net/mail"
"net/url"
"regexp"
"strings"
"time"
"unicode/utf8"
"google.golang.org/protobuf/types/known/anypb"
)
// ensure the imports are used
var (
_ = bytes.MinRead
_ = errors.New("")
_ = fmt.Print
_ = utf8.UTFMax
_ = (*regexp.Regexp)(nil)
_ = (*strings.Reader)(nil)
_ = net.IPv4len
_ = time.Duration(0)
_ = (*url.URL)(nil)
_ = (*mail.Address)(nil)
_ = anypb.Any{}
)
// Validate checks the field values on Reply with the rules defined in the
// proto definition for this message. If any rules are violated, the first
// error encountered is returned, or nil if there are no violations.
func (m *Reply) Validate() error {
return m.validate(false)
}
// ValidateAll checks the field values on Reply with the rules defined in the
// proto definition for this message. If any rules are violated, the result is
// a list of violation errors wrapped in ReplyMultiError, or nil if none found.
func (m *Reply) ValidateAll() error {
return m.validate(true)
}
func (m *Reply) validate(all bool) error {
if m == nil {
return nil
}
var errors []error
// no validation rules for Message
if len(errors) > 0 {
return ReplyMultiError(errors)
}
return nil
}
// ReplyMultiError is an error wrapping multiple validation errors returned by
// Reply.ValidateAll() if the designated constraints aren't met.
type ReplyMultiError []error
// Error returns a concatenation of all the error messages it wraps.
func (m ReplyMultiError) Error() string {
var msgs []string
for _, err := range m {
msgs = append(msgs, err.Error())
}
return strings.Join(msgs, "; ")
}
// AllErrors returns a list of validation violation errors.
func (m ReplyMultiError) AllErrors() []error { return m }
// ReplyValidationError is the validation error returned by Reply.Validate if
// the designated constraints aren't met.
type ReplyValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e ReplyValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e ReplyValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e ReplyValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e ReplyValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e ReplyValidationError) ErrorName() string { return "ReplyValidationError" }
// Error satisfies the builtin error interface
func (e ReplyValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sReply.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = ReplyValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = ReplyValidationError{}
// Validate checks the field values on Request with the rules defined in the
// proto definition for this message. If any rules are violated, the first
// error encountered is returned, or nil if there are no violations.
func (m *Request) Validate() error {
return m.validate(false)
}
// ValidateAll checks the field values on Request with the rules defined in the
// proto definition for this message. If any rules are violated, the result is
// a list of violation errors wrapped in RequestMultiError, or nil if none found.
func (m *Request) ValidateAll() error {
return m.validate(true)
}
func (m *Request) validate(all bool) error {
if m == nil {
return nil
}
var errors []error
if m.GetId() <= 0 {
err := RequestValidationError{
field: "Id",
reason: "value must be greater than 0",
}
if !all {
return err
}
errors = append(errors, err)
}
if val := m.GetAge(); val <= 0 || val >= 120 {
err := RequestValidationError{
field: "Age",
reason: "value must be inside range (0, 120)",
}
if !all {
return err
}
errors = append(errors, err)
}
if _, ok := _Request_Code_InLookup[m.GetCode()]; !ok {
err := RequestValidationError{
field: "Code",
reason: "value must be in list [1 2 3]",
}
if !all {
return err
}
errors = append(errors, err)
}
if _, ok := _Request_Score_NotInLookup[m.GetScore()]; ok {
err := RequestValidationError{
field: "Score",
reason: "value must not be in list [0 99.99]",
}
if !all {
return err
}
errors = append(errors, err)
}
if m.GetState() != true {
err := RequestValidationError{
field: "State",
reason: "value must equal true",
}
if !all {
return err
}
errors = append(errors, err)
}
if m.GetPath() != "/hello" {
err := RequestValidationError{
field: "Path",
reason: "value must equal /hello",
}
if !all {
return err
}
errors = append(errors, err)
}
if utf8.RuneCountInString(m.GetPhone()) != 11 {
err := RequestValidationError{
field: "Phone",
reason: "value length must be 11 runes",
}
if !all {
return err
}
errors = append(errors, err)
}
if utf8.RuneCountInString(m.GetExplain()) < 3 {
err := RequestValidationError{
field: "Explain",
reason: "value length must be at least 3 runes",
}
if !all {
return err
}
errors = append(errors, err)
}
if l := utf8.RuneCountInString(m.GetName()); l < 1 || l > 10 {
err := RequestValidationError{
field: "Name",
reason: "value length must be between 1 and 10 runes, inclusive",
}
if !all {
return err
}
errors = append(errors, err)
}
if !_Request_Card_Pattern.MatchString(m.GetCard()) {
err := RequestValidationError{
field: "Card",
reason: "value does not match regex pattern \"(?i)^[0-9a-f]+$\"",
}
if !all {
return err
}
errors = append(errors, err)
}
if m.GetInfo() == nil {
err := RequestValidationError{
field: "Info",
reason: "value is required",
}
if !all {
return err
}
errors = append(errors, err)
}
if all {
switch v := interface{}(m.GetInfo()).(type) {
case interface{ ValidateAll() error }:
if err := v.ValidateAll(); err != nil {
errors = append(errors, RequestValidationError{
field: "Info",
reason: "embedded message failed validation",
cause: err,
})
}
case interface{ Validate() error }:
if err := v.Validate(); err != nil {
errors = append(errors, RequestValidationError{
field: "Info",
reason: "embedded message failed validation",
cause: err,
})
}
}
} else if v, ok := interface{}(m.GetInfo()).(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
return RequestValidationError{
field: "Info",
reason: "embedded message failed validation",
cause: err,
}
}
}
if len(errors) > 0 {
return RequestMultiError(errors)
}
return nil
}
// RequestMultiError is an error wrapping multiple validation errors returned
// by Request.ValidateAll() if the designated constraints aren't met.
type RequestMultiError []error
// Error returns a concatenation of all the error messages it wraps.
func (m RequestMultiError) Error() string {
var msgs []string
for _, err := range m {
msgs = append(msgs, err.Error())
}
return strings.Join(msgs, "; ")
}
// AllErrors returns a list of validation violation errors.
func (m RequestMultiError) AllErrors() []error { return m }
// RequestValidationError is the validation error returned by Request.Validate
// if the designated constraints aren't met.
type RequestValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e RequestValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e RequestValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e RequestValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e RequestValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e RequestValidationError) ErrorName() string { return "RequestValidationError" }
// Error satisfies the builtin error interface
func (e RequestValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sRequest.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = RequestValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = RequestValidationError{}
var _Request_Code_InLookup = map[uint32]struct{}{
1: {},
2: {},
3: {},
}
var _Request_Score_NotInLookup = map[float32]struct{}{
0: {},
99.99: {},
}
var _Request_Card_Pattern = regexp.MustCompile("(?i)^[0-9a-f]+$")
// Validate checks the field values on Info with the rules defined in the proto
// definition for this message. If any rules are violated, the first error
// encountered is returned, or nil if there are no violations.
func (m *Info) Validate() error {
return m.validate(false)
}
// ValidateAll checks the field values on Info with the rules defined in the
// proto definition for this message. If any rules are violated, the result is
// a list of violation errors wrapped in InfoMultiError, or nil if none found.
func (m *Info) ValidateAll() error {
return m.validate(true)
}
func (m *Info) validate(all bool) error {
if m == nil {
return nil
}
var errors []error
// no validation rules for Address
if len(errors) > 0 {
return InfoMultiError(errors)
}
return nil
}
// InfoMultiError is an error wrapping multiple validation errors returned by
// Info.ValidateAll() if the designated constraints aren't met.
type InfoMultiError []error
// Error returns a concatenation of all the error messages it wraps.
func (m InfoMultiError) Error() string {
var msgs []string
for _, err := range m {
msgs = append(msgs, err.Error())
}
return strings.Join(msgs, "; ")
}
// AllErrors returns a list of validation violation errors.
func (m InfoMultiError) AllErrors() []error { return m }
// InfoValidationError is the validation error returned by Info.Validate if the
// designated constraints aren't met.
type InfoValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e InfoValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e InfoValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e InfoValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e InfoValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e InfoValidationError) ErrorName() string { return "InfoValidationError" }
// Error satisfies the builtin error interface
func (e InfoValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sInfo.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = InfoValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = InfoValidationError{}

@ -0,0 +1,43 @@
syntax = "proto3";
package api.example;
option go_package = "github.com/go-kratos/kratos/examples/validate/api/v1;v1";
option java_multiple_files = true;
option java_package = "validate.api.v1";
import "google/api/annotations.proto";
// the validate rules:
// https://github.com/envoyproxy/protoc-gen-validate
import "validate/validate.proto";
service ExampleService {
rpc TestValidate (Request) returns (Reply) {
option (google.api.http) = {
post: "/v1/validate"
body: "*"
};
}
}
message Reply {
string message = 1;
}
message Request {
int64 id = 1 [(validate.rules).int64 = {gt: 0}];
int32 age = 2 [(validate.rules).int32 = {gt:0, lt: 120}];
uint32 code = 3 [(validate.rules).uint32 = {in: [1,2,3]}];
float score = 4 [(validate.rules).float = {not_in: [0, 99.99]}];
bool state = 5 [(validate.rules).bool.const = true];
string path = 6 [(validate.rules).string.const = "/hello"];
string phone = 7 [(validate.rules).string.len = 11];
string explain = 8 [(validate.rules).string.min_len = 3];
string name = 9 [(validate.rules).string = {min_len: 1, max_len: 10}];
string card = 10 [(validate.rules).string.pattern = "(?i)^[0-9a-f]+$"];
Info info = 11 [(validate.rules).message.required = true];
}
message Info {
string address = 1;
}

@ -0,0 +1,101 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package v1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// ExampleServiceClient is the client API for ExampleService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type ExampleServiceClient interface {
TestValidate(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Reply, error)
}
type exampleServiceClient struct {
cc grpc.ClientConnInterface
}
func NewExampleServiceClient(cc grpc.ClientConnInterface) ExampleServiceClient {
return &exampleServiceClient{cc}
}
func (c *exampleServiceClient) TestValidate(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/api.example.ExampleService/TestValidate", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ExampleServiceServer is the server API for ExampleService service.
// All implementations must embed UnimplementedExampleServiceServer
// for forward compatibility
type ExampleServiceServer interface {
TestValidate(context.Context, *Request) (*Reply, error)
mustEmbedUnimplementedExampleServiceServer()
}
// UnimplementedExampleServiceServer must be embedded to have forward compatible implementations.
type UnimplementedExampleServiceServer struct {
}
func (UnimplementedExampleServiceServer) TestValidate(context.Context, *Request) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method TestValidate not implemented")
}
func (UnimplementedExampleServiceServer) mustEmbedUnimplementedExampleServiceServer() {}
// UnsafeExampleServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to ExampleServiceServer will
// result in compilation errors.
type UnsafeExampleServiceServer interface {
mustEmbedUnimplementedExampleServiceServer()
}
func RegisterExampleServiceServer(s grpc.ServiceRegistrar, srv ExampleServiceServer) {
s.RegisterService(&ExampleService_ServiceDesc, srv)
}
func _ExampleService_TestValidate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Request)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ExampleServiceServer).TestValidate(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.example.ExampleService/TestValidate",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ExampleServiceServer).TestValidate(ctx, req.(*Request))
}
return interceptor(ctx, in, info, handler)
}
// ExampleService_ServiceDesc is the grpc.ServiceDesc for ExampleService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ExampleService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "api.example.ExampleService",
HandlerType: (*ExampleServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "TestValidate",
Handler: _ExampleService_TestValidate_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "example.proto",
}

@ -0,0 +1,69 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
// versions:
// protoc-gen-go-http v2.0.0-rc3
package v1
import (
context "context"
http "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(context.Context)
var _ = binding.EncodeURL
const _ = http.SupportPackageIsVersion1
type ExampleServiceHTTPServer interface {
TestValidate(context.Context, *Request) (*Reply, error)
}
func RegisterExampleServiceHTTPServer(s *http.Server, srv ExampleServiceHTTPServer) {
r := s.Route("/")
r.POST("/v1/validate/", _ExampleService_TestValidate0_HTTP_Handler(srv))
}
func _ExampleService_TestValidate0_HTTP_Handler(srv ExampleServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in Request
if err := ctx.Bind(&in); err != nil {
return err
}
http.SetOperation(ctx, "/api.example.ExampleService/TestValidate")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.TestValidate(ctx, req.(*Request))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*Reply)
return ctx.Result(200, reply)
}
}
type ExampleServiceHTTPClient interface {
TestValidate(ctx context.Context, req *Request, opts ...http.CallOption) (rsp *Reply, err error)
}
type ExampleServiceHTTPClientImpl struct {
cc *http.Client
}
func NewExampleServiceHTTPClient(client *http.Client) ExampleServiceHTTPClient {
return &ExampleServiceHTTPClientImpl{client}
}
func (c *ExampleServiceHTTPClientImpl) TestValidate(ctx context.Context, in *Request, opts ...http.CallOption) (*Reply, error) {
var out Reply
path := binding.EncodeURL("/v1/validate/", in, false)
opts = append(opts, http.Operation("/api.example.ExampleService/TestValidate"))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}

@ -0,0 +1,55 @@
package main
import (
"context"
"log"
"github.com/go-kratos/kratos/examples/validate/api"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/middleware/validate"
"github.com/go-kratos/kratos/v2/transport/grpc"
"github.com/go-kratos/kratos/v2/transport/http"
)
// go build -ldflags "-X main.Version=x.y.z"
var (
// Name is the name of the compiled software.
Name = "errors"
// Version is the version of the compiled software.
Version = "v1.0.0"
)
type server struct {
v1.UnimplementedExampleServiceServer
}
func (s *server) TestValidate(ctx context.Context, in *v1.Request) (*v1.Reply, error) {
return &v1.Reply{Message: "ok"}, nil
}
func main() {
s := &server{}
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
validate.Validator(),
))
httpSrv := http.NewServer(
http.Address(":8000"),
http.Middleware(
validate.Validator(),
))
v1.RegisterExampleServiceServer(grpcSrv, s)
v1.RegisterExampleServiceHTTPServer(httpSrv, s)
app := kratos.New(
kratos.Name(Name),
kratos.Server(
grpcSrv,
httpSrv,
),
)
if err := app.Run(); err != nil {
log.Fatal(err)
}
}
Loading…
Cancel
Save