1
0
mirror of https://github.com/go-kratos/kratos.git synced 2025-10-30 23:47:59 +02:00

feature(middleware/validate): migrate from PGV to protovalidate, since PGV has entered in maintenance (#3498)

* feature(contrib/middleware/validate): provide new validator middleware

* chore: upgrade go version
This commit is contained in:
DCjanus
2025-01-27 09:56:23 +08:00
committed by GitHub
parent ff30a75a86
commit 54f8e11d9f
43 changed files with 5433 additions and 31 deletions

View File

@@ -13,7 +13,7 @@ jobs:
build:
strategy:
matrix:
go: [ 1.20.x, 1.21.x, 1.22.x ]
go: [ 1.21.x, 1.22.x, 1.23.x ]
name: build & test
runs-on: ubuntu-latest
services:

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/cmd/kratos/v2
go 1.19
go 1.21
require (
github.com/AlecAivazis/survey/v2 v2.3.7

View File

@@ -25,7 +25,7 @@ func TestModulePath(t *testing.T) {
mod := `module github.com/go-kratos/kratos/v2
go 1.19`
go 1.21`
_, err = f.WriteString(mod)
if err != nil {
t.Fatal(err)

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2
go 1.19
go 1.21
require (
golang.org/x/text v0.3.8

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2
go 1.19
go 1.21
require (
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/config/apollo/v2
go 1.19
go 1.21
require (
github.com/apolloconfig/agollo/v4 v4.3.1

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/config/consul/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/config/etcd/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/config/kubernetes/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/config/nacos/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/config/polaris/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/encoding/msgpack/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/errortracker/sentry/v2
go 1.19
go 1.21
require (
github.com/getsentry/sentry-go v0.25.0

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/log/aliyun/v2
go 1.19
go 1.21
require (
github.com/aliyun/aliyun-log-go-sdk v0.1.75

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/log/fluent/v2
go 1.19
go 1.21
require (
github.com/fluent/fluent-logger-golang v1.9.0

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/log/logrus/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/log/tencent/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/log/zap/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/log/zerolog/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -0,0 +1,15 @@
# Validator Middleware for Kratos Project
This module provides a middleware for Kratos to validate request parameters, using schema defined in `.proto` files.
There used to be a middleware named `Validator` in Kratos, which calls the generated validation functions
from [PGV](https://github.com/bufbuild/protoc-gen-validate) at runtime. Since PGV has been
in [maintenance](https://github.com/bufbuild/protoc-gen-validate/commit/4a8ffc4942463929c4289407cd4b8c8328ff5422), and
recommend using [protovalidate](https://github.com/bufbuild/protovalidate) as an alternative.
That's why we provide a new middleware that uses the schema definitions and validation functions provided by
protovalidate.
protovalidate no longer requires code generation at build time, but for compatibility with existing Kratos
projects, we enable the legacy mode of protovalidate. For most users, no changes are needed to existing code. **But for
users who have manually implemented the Validator interface, you need to migrate the relevant implementation yourself**.

View File

@@ -0,0 +1,24 @@
module github.com/go-kratos/kratos/contrib/middleware/validate/v2
go 1.21.1
require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.2-20241127180247-a33202765966.1
github.com/bufbuild/protovalidate-go v0.8.2
github.com/envoyproxy/protoc-gen-validate v1.1.0
github.com/go-kratos/kratos/v2 v2.8.3
google.golang.org/protobuf v1.36.2
)
require (
cel.dev/expr v0.18.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/google/cel-go v0.22.1 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect
google.golang.org/grpc v1.65.0 // indirect
)

View File

@@ -0,0 +1,51 @@
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.2-20241127180247-a33202765966.1 h1:BICM6du/XzvEgeorNo4xgohK3nMTmEPViGyd5t7xVqk=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.2-20241127180247-a33202765966.1/go.mod h1:JnMVLi3qrNYPODVpEKG7UjHLl/d2zR221e66YCSmP2Q=
cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo=
cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/bufbuild/protovalidate-go v0.8.2 h1:sgzXHkHYP6HnAsL2Rd3I1JxkYUyEQUv9awU1PduMxbM=
github.com/bufbuild/protovalidate-go v0.8.2/go.mod h1:K6w8iPNAXBoIivVueSELbUeUl+MmeTQfCDSug85pn3M=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
github.com/go-kratos/kratos/v2 v2.8.3 h1:kkNBq0gvdX+b8cbaN+p6Sdh95DgMhx7GimefXb4o7Ss=
github.com/go-kratos/kratos/v2 v2.8.3/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40=
github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw=
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -0,0 +1,3 @@
package testdata
//go:generate protoc -I . -I ../../../../../third_party --go_out=paths=source_relative:. ./test.proto

View File

@@ -0,0 +1,258 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.0
// protoc v5.28.3
// source: test.proto
package testdata
import (
_ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
_ "github.com/envoyproxy/protoc-gen-validate/validate"
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 Legacy struct {
state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Legacy) Reset() {
*x = Legacy{}
mi := &file_test_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Legacy) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Legacy) ProtoMessage() {}
func (x *Legacy) ProtoReflect() protoreflect.Message {
mi := &file_test_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Legacy.ProtoReflect.Descriptor instead.
func (*Legacy) Descriptor() ([]byte, []int) {
return file_test_proto_rawDescGZIP(), []int{0}
}
func (x *Legacy) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Legacy) GetAge() int32 {
if x != nil {
return x.Age
}
return 0
}
type Mixed struct {
state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Mixed) Reset() {
*x = Mixed{}
mi := &file_test_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Mixed) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Mixed) ProtoMessage() {}
func (x *Mixed) ProtoReflect() protoreflect.Message {
mi := &file_test_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Mixed.ProtoReflect.Descriptor instead.
func (*Mixed) Descriptor() ([]byte, []int) {
return file_test_proto_rawDescGZIP(), []int{1}
}
func (x *Mixed) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Mixed) GetAge() int32 {
if x != nil {
return x.Age
}
return 0
}
type Modern struct {
state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Modern) Reset() {
*x = Modern{}
mi := &file_test_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Modern) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Modern) ProtoMessage() {}
func (x *Modern) ProtoReflect() protoreflect.Message {
mi := &file_test_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Modern.ProtoReflect.Descriptor instead.
func (*Modern) Descriptor() ([]byte, []int) {
return file_test_proto_rawDescGZIP(), []int{2}
}
func (x *Modern) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Modern) GetAge() int32 {
if x != nil {
return x.Age
}
return 0
}
var File_test_proto protoreflect.FileDescriptor
var file_test_proto_rawDesc = []byte{
0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x74, 0x65,
0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 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, 0x40, 0x0a, 0x06,
0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x05, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
0x42, 0x07, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x20, 0x12, 0x52, 0x03, 0x61, 0x67, 0x65, 0x22, 0x3f,
0x0a, 0x05, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x05, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x05, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x20, 0x12, 0x52, 0x03, 0x61, 0x67, 0x65, 0x22,
0x40, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x05,
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x05, 0x42, 0x07, 0xba, 0x48, 0x04, 0x1a, 0x02, 0x20, 0x12, 0x52, 0x03, 0x61, 0x67,
0x65, 0x42, 0x4b, 0x5a, 0x49, 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, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x2f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77,
0x61, 0x72, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x69, 0x6e, 0x74,
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_test_proto_rawDescOnce sync.Once
file_test_proto_rawDescData = file_test_proto_rawDesc
)
func file_test_proto_rawDescGZIP() []byte {
file_test_proto_rawDescOnce.Do(func() {
file_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_proto_rawDescData)
})
return file_test_proto_rawDescData
}
var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_test_proto_goTypes = []any{
(*Legacy)(nil), // 0: testdata.Legacy
(*Mixed)(nil), // 1: testdata.Mixed
(*Modern)(nil), // 2: testdata.Modern
}
var file_test_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_test_proto_init() }
func file_test_proto_init() {
if File_test_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_test_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_test_proto_goTypes,
DependencyIndexes: file_test_proto_depIdxs,
MessageInfos: file_test_proto_msgTypes,
}.Build()
File_test_proto = out.File
file_test_proto_rawDesc = nil
file_test_proto_goTypes = nil
file_test_proto_depIdxs = nil
}

View File

@@ -0,0 +1,23 @@
syntax = "proto3";
package testdata;
import "buf/validate/validate.proto";
import "validate/validate.proto";
option go_package = "github.com/go-kratos/kratos/contrib/middleware/validate/internal/testdata";
message Legacy {
string name = 1 [(validate.rules).string.min_len = 5];
int32 age = 2 [(validate.rules).int32.gt = 18];
}
message Mixed {
string name = 1 [(buf.validate.field).string.min_len = 5];
int32 age = 2 [(validate.rules).int32.gt = 18];
}
message Modern {
string name = 1 [(buf.validate.field).string.min_len = 5];
int32 age = 2 [(buf.validate.field).int32.gt = 18];
}

View File

@@ -0,0 +1,35 @@
package validate
import (
"context"
"fmt"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/bufbuild/protovalidate-go"
"github.com/bufbuild/protovalidate-go/legacy"
"google.golang.org/protobuf/proto"
)
// ProtoValidate is a middleware that validates the request message with [protovalidate](https://github.com/bufbuild/protovalidate)
func ProtoValidate() middleware.Middleware {
validator, err := protovalidate.New(
// Some projects may still be using PGV, turn on legacy support to handle this.
legacy.WithLegacySupport(legacy.ModeMerge),
)
if err != nil {
panic(fmt.Errorf("protovalidate.New() error: %w", err))
}
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
if msg, ok := req.(proto.Message); ok {
if err := validator.Validate(msg); err != nil {
return nil, errors.BadRequest("VALIDATOR", err.Error()).WithCause(err)
}
}
return handler(ctx, req)
}
}
}

View File

@@ -0,0 +1,82 @@
package validate
import (
"context"
"testing"
"google.golang.org/protobuf/proto"
"github.com/go-kratos/kratos/contrib/middleware/validate/v2/internal/testdata"
kerrors "github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/middleware"
)
type testcase struct {
name string
req proto.Message
err bool
}
func TestTable(t *testing.T) {
var mock middleware.Handler = func(context.Context, interface{}) (interface{}, error) { return nil, nil }
tests := []testcase{
{
name: "valid_legacy",
req: &testdata.Legacy{Name: "testcase", Age: 19},
err: false,
},
{
name: "invalid_legacy1",
req: &testdata.Legacy{Name: "testcase", Age: 10},
err: true,
},
{
name: "invalid_legacy2",
req: &testdata.Legacy{Name: "test", Age: 100},
err: true,
},
{
name: "valid_mixed",
req: &testdata.Mixed{Name: "testcase", Age: 19},
err: false,
},
{
name: "invalid_mixed1",
req: &testdata.Mixed{Name: "testcase", Age: 10},
err: true,
},
{
name: "invalid_mixed2",
req: &testdata.Mixed{Name: "test", Age: 100},
err: true,
},
{
name: "valid_modern",
req: &testdata.Modern{Name: "testcase", Age: 19},
err: false,
},
{
name: "invalid_modern1",
req: &testdata.Modern{Name: "testcase", Age: 10},
err: true,
},
{
name: "invalid_modern2",
req: &testdata.Modern{Name: "test", Age: 100},
err: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
handle := ProtoValidate()(mock)
_, err := handle(context.Background(), test.req)
expect := test.err
actual := kerrors.IsBadRequest(err)
if expect != actual {
t.Errorf("case %s expect %v, actual %v, err %v", test.name, expect, actual, err)
}
})
}
}

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/opensergo/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/polaris/v2
go 1.19
go 1.21
require (
github.com/go-kratos/aegis v0.2.0

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/registry/consul/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/registry/discovery/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/registry/etcd/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/registry/eureka/v2
go 1.19
go 1.21
require github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/registry/kubernetes/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/registry/nacos/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/registry/polaris/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/registry/servicecomb/v2
go 1.19
go 1.21
require (
github.com/go-chassis/cari v0.6.0

View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/contrib/registry/zookeeper/v2
go 1.19
go 1.21
require (
github.com/go-kratos/kratos/v2 v2.8.3

2
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/go-kratos/kratos/v2
go 1.20
go 1.21
require (
dario.cat/mergo v1.0.0

4
go.sum
View File

@@ -1,7 +1,9 @@
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY=
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -9,6 +11,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/envoyproxy/go-control-plane v0.11.2-0.20230627204322-7d0032219fcb h1:kxNVXsNro/lpR5WD+P1FI/yUHn2G03Glber3k8cQL2Y=
github.com/envoyproxy/go-control-plane v0.11.2-0.20230627204322-7d0032219fcb/go.mod h1:GxGqnjWzl1Gz8WfAfMJSfhvsi4EPZayRb25nLHDWXyA=
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-kratos/aegis v0.2.0 h1:dObzCDWn3XVjUkgxyBp6ZeWtx/do0DPZ7LY3yNSJLUQ=
@@ -31,6 +34,7 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=

View File

@@ -12,6 +12,8 @@ type validator interface {
}
// Validator is a validator middleware.
//
// Deprecated: use github.com/go-kratos/kratos/contrib/middleware/validate/v2.ProtoValidate instead.
func Validator() middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {

3
third_party/buf/validate/README.md vendored Normal file
View File

@@ -0,0 +1,3 @@
# protovalidate
* https://github.com/bufbuild/protovalidate

4902
third_party/buf/validate/validate.proto vendored Normal file

File diff suppressed because it is too large Load Diff