From 1759f91cd1bc7ec1f3ed5c35340dc2c8ecceef31 Mon Sep 17 00:00:00 2001 From: Ryan D McGuire Date: Mon, 21 Jul 2025 16:39:00 -0400 Subject: [PATCH] fix buf validate, add sample field validation --- api/demo/app/v1alpha1/app.pb.go | 13 +- api/demo/app/v1alpha1/app.pb.validate.go | 275 ----------------------- buf.gen.yaml | 4 - proto/demo/app/v1alpha1/app.proto | 5 +- 4 files changed, 10 insertions(+), 287 deletions(-) delete mode 100644 api/demo/app/v1alpha1/app.pb.validate.go diff --git a/api/demo/app/v1alpha1/app.pb.go b/api/demo/app/v1alpha1/app.pb.go index 872b096..a8dd4f9 100644 --- a/api/demo/app/v1alpha1/app.pb.go +++ b/api/demo/app/v1alpha1/app.pb.go @@ -7,6 +7,7 @@ package demo import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -143,15 +144,15 @@ var File_demo_app_v1alpha1_app_proto protoreflect.FileDescriptor const file_demo_app_v1alpha1_app_proto_rawDesc = "" + "\n" + - "\x1bdemo/app/v1alpha1/app.proto\x12\x11demo.app.v1alpha1\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/protobuf/timestamp.proto\">\n" + - "\x0eGetDemoRequest\x12\x1f\n" + - "\blanguage\x18\x01 \x01(\tH\x00R\blanguage\x88\x01\x01B\v\n" + - "\t_language\"\x93\x01\n" + + "\x1bdemo/app/v1alpha1/app.proto\x12\x11demo.app.v1alpha1\x1a\x1bbuf/validate/validate.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"G\n" + + "\x0eGetDemoRequest\x12(\n" + + "\blanguage\x18\x01 \x01(\tB\a\xbaH\x04r\x02\x10\x02H\x00R\blanguage\x88\x01\x01B\v\n" + + "\t_language\"\x9c\x01\n" + "\x0fGetDemoResponse\x128\n" + "\ttimestamp\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\x12\x12\n" + "\x04fact\x18\x02 \x01(\tR\x04fact\x12\x16\n" + - "\x06source\x18\x03 \x01(\tR\x06source\x12\x1a\n" + - "\blanguage\x18\x04 \x01(\tR\blanguage2z\n" + + "\x06source\x18\x03 \x01(\tR\x06source\x12#\n" + + "\blanguage\x18\x04 \x01(\tB\a\xbaH\x04r\x02\x10\x02R\blanguage2z\n" + "\x0eDemoAppService\x12h\n" + "\aGetDemo\x12!.demo.app.v1alpha1.GetDemoRequest\x1a\".demo.app.v1alpha1.GetDemoResponse\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/v1alpha1/demoB\xd5\x01\n" + "\x15com.demo.app.v1alpha1B\bAppProtoP\x01ZLgitea.libretechconsulting.com/rmcguire/go-server-with-otel/api/v1alpha1/demo\xa2\x02\x03DAX\xaa\x02\x11Demo.App.V1alpha1\xca\x02\x11Demo\\App\\V1alpha1\xe2\x02\x1dDemo\\App\\V1alpha1\\GPBMetadata\xea\x02\x13Demo::App::V1alpha1b\x06proto3" diff --git a/api/demo/app/v1alpha1/app.pb.validate.go b/api/demo/app/v1alpha1/app.pb.validate.go deleted file mode 100644 index 3a36825..0000000 --- a/api/demo/app/v1alpha1/app.pb.validate.go +++ /dev/null @@ -1,275 +0,0 @@ -// Code generated by protoc-gen-validate. DO NOT EDIT. -// source: demo/app/v1alpha1/app.proto - -package demo - -import ( - "bytes" - "errors" - "fmt" - "net" - "net/mail" - "net/url" - "regexp" - "sort" - "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{} - _ = sort.Sort -) - -// Validate checks the field values on GetDemoRequest 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 *GetDemoRequest) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on GetDemoRequest 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 GetDemoRequestMultiError, -// or nil if none found. -func (m *GetDemoRequest) ValidateAll() error { - return m.validate(true) -} - -func (m *GetDemoRequest) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if m.Language != nil { - // no validation rules for Language - } - - if len(errors) > 0 { - return GetDemoRequestMultiError(errors) - } - - return nil -} - -// GetDemoRequestMultiError is an error wrapping multiple validation errors -// returned by GetDemoRequest.ValidateAll() if the designated constraints -// aren't met. -type GetDemoRequestMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m GetDemoRequestMultiError) Error() string { - msgs := make([]string, 0, len(m)) - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m GetDemoRequestMultiError) AllErrors() []error { return m } - -// GetDemoRequestValidationError is the validation error returned by -// GetDemoRequest.Validate if the designated constraints aren't met. -type GetDemoRequestValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e GetDemoRequestValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e GetDemoRequestValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e GetDemoRequestValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e GetDemoRequestValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e GetDemoRequestValidationError) ErrorName() string { return "GetDemoRequestValidationError" } - -// Error satisfies the builtin error interface -func (e GetDemoRequestValidationError) 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 %sGetDemoRequest.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = GetDemoRequestValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = GetDemoRequestValidationError{} - -// Validate checks the field values on GetDemoResponse 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 *GetDemoResponse) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on GetDemoResponse 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 -// GetDemoResponseMultiError, or nil if none found. -func (m *GetDemoResponse) ValidateAll() error { - return m.validate(true) -} - -func (m *GetDemoResponse) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - if all { - switch v := interface{}(m.GetTimestamp()).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, GetDemoResponseValidationError{ - field: "Timestamp", - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, GetDemoResponseValidationError{ - field: "Timestamp", - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(m.GetTimestamp()).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return GetDemoResponseValidationError{ - field: "Timestamp", - reason: "embedded message failed validation", - cause: err, - } - } - } - - // no validation rules for Fact - - // no validation rules for Source - - // no validation rules for Language - - if len(errors) > 0 { - return GetDemoResponseMultiError(errors) - } - - return nil -} - -// GetDemoResponseMultiError is an error wrapping multiple validation errors -// returned by GetDemoResponse.ValidateAll() if the designated constraints -// aren't met. -type GetDemoResponseMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m GetDemoResponseMultiError) Error() string { - msgs := make([]string, 0, len(m)) - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m GetDemoResponseMultiError) AllErrors() []error { return m } - -// GetDemoResponseValidationError is the validation error returned by -// GetDemoResponse.Validate if the designated constraints aren't met. -type GetDemoResponseValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e GetDemoResponseValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e GetDemoResponseValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e GetDemoResponseValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e GetDemoResponseValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e GetDemoResponseValidationError) ErrorName() string { return "GetDemoResponseValidationError" } - -// Error satisfies the builtin error interface -func (e GetDemoResponseValidationError) 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 %sGetDemoResponse.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = GetDemoResponseValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = GetDemoResponseValidationError{} diff --git a/buf.gen.yaml b/buf.gen.yaml index 6ec8cf2..81f79b9 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -14,10 +14,6 @@ plugins: opt: - paths=source_relative - require_unimplemented_servers=false - - remote: buf.build/bufbuild/validate-go - out: api - opt: - - paths=source_relative - remote: buf.build/grpc-ecosystem/gateway out: api opt: diff --git a/proto/demo/app/v1alpha1/app.proto b/proto/demo/app/v1alpha1/app.proto index 2301aa3..e371fc6 100644 --- a/proto/demo/app/v1alpha1/app.proto +++ b/proto/demo/app/v1alpha1/app.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package demo.app.v1alpha1; +import "buf/validate/validate.proto"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; @@ -9,7 +10,7 @@ option go_package = "gitea.libretechconsulting.com/rmcguire/go-server-with-otel/ // Options for random fact, in this case // just a language message GetDemoRequest { - optional string language = 1; + optional string language = 1 [(buf.validate.field).string.min_len = 2]; } // Returns a randome fact, because this is a demo app @@ -18,7 +19,7 @@ message GetDemoResponse { google.protobuf.Timestamp timestamp = 1; string fact = 2; string source = 3; - string language = 4; + string language = 4 [(buf.validate.field).string.min_len = 2]; } service DemoAppService {