feat: implement rpc field validation
parent
878b9f38a2
commit
e4435e0ec2
|
@ -3,7 +3,9 @@ managed:
|
|||
enabled: true
|
||||
go_package_prefix:
|
||||
default: github.com/sundowndev/grpc-api-example/proto
|
||||
except:
|
||||
- buf.build/googleapis/googleapis
|
||||
- buf.build/bufbuild/protovalidate
|
||||
plugins:
|
||||
- plugin: buf.build/protocolbuffers/go:v1.30.0
|
||||
out: proto
|
||||
|
|
7
go.mod
7
go.mod
|
@ -10,12 +10,19 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.32.0-20240212200630-3014d81c3a48.1 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
||||
github.com/bufbuild/protovalidate-go v0.5.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/cel-go v0.19.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/net v0.20.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
24
go.sum
24
go.sum
|
@ -1,3 +1,10 @@
|
|||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.32.0-20240212200630-3014d81c3a48.1 h1:rOe/itdO7+9cWOnKqvpn1K7VmTDwp3vI4juPz6aNQbc=
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.32.0-20240212200630-3014d81c3a48.1/go.mod h1:tiTMKD8j6Pd/D2WzREoweufjzaJKHZg35f/VGcZ2v3I=
|
||||
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.5.2 h1:MPNZd6F2ekGWjWVQDv8lEYOX8ndSOzMnmTaGbDZWIcg=
|
||||
github.com/bufbuild/protovalidate-go v0.5.2/go.mod h1:DWCNjFl/HwtBiHyN5/3lKA+0MgXOlAoc3jk8Ps3iN+s=
|
||||
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/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||
|
@ -5,12 +12,24 @@ github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx
|
|||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/cel-go v0.19.0 h1:vVgaZoHPBDd1lXCYGQOh5A06L4EtuIfmqQ/qnSXSKiU=
|
||||
github.com/google/cel-go v0.19.0/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
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.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
|
@ -18,6 +37,9 @@ golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
|
||||
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
|
||||
|
@ -28,5 +50,7 @@ google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7
|
|||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
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=
|
||||
|
|
7
main.go
7
main.go
|
@ -17,8 +17,11 @@ func main() {
|
|||
log := grpclog.NewLoggerV2(os.Stdout, io.Discard, io.Discard)
|
||||
grpclog.SetLoggerV2(log)
|
||||
|
||||
addr := "0.0.0.0:10000" // TODO: handle this with CLI flags
|
||||
srv := server.NewServer(insecure.NewCredentials()) // TODO: Replace with your own certificate!
|
||||
addr := "0.0.0.0:10000" // TODO: handle this with CLI flags
|
||||
srv, err := server.NewServer(insecure.NewCredentials()) // TODO: Replace with your own certificate!
|
||||
if err != nil {
|
||||
log.Fatal("failed to initialize server: %v", err)
|
||||
}
|
||||
|
||||
// Serve gRPC Server
|
||||
log.Info("Serving gRPC on https://", addr)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# Generated by buf. DO NOT EDIT.
|
||||
version: v1
|
||||
deps:
|
||||
- remote: buf.build
|
||||
owner: bufbuild
|
||||
repository: protovalidate
|
||||
commit: f05a6f4403ce4327bae4f50f281c3ed0
|
||||
digest: shake256:668a0661b8df44d41839194896329330965fc215f3d2f88057fd60eeb759c2daf6cc6edfdd13b2a653d49fe2896ebedcb1a33c4c5b2dd10919f03ffb7fc52ae6
|
||||
- remote: buf.build
|
||||
owner: googleapis
|
||||
repository: googleapis
|
||||
commit: 7e6f6e774e29406da95bd61cdcdbc8bc
|
||||
digest: shake256:fe43dd2265ea0c07d76bd925eeba612667cf4c948d2ce53d6e367e1b4b3cb5fa69a51e6acb1a6a50d32f894f054a35e6c0406f6808a483f2752e10c866ffbf73
|
|
@ -2,6 +2,7 @@ version: v1
|
|||
name: buf.build/sundowndev/grpc-api-example
|
||||
deps:
|
||||
- buf.build/googleapis/googleapis
|
||||
- buf.build/bufbuild/protovalidate
|
||||
lint:
|
||||
use:
|
||||
- DEFAULT
|
|
@ -7,6 +7,7 @@
|
|||
package notesv1
|
||||
|
||||
import (
|
||||
_ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
|
@ -267,39 +268,40 @@ var File_notes_v1_notes_proto protoreflect.FileDescriptor
|
|||
var file_notes_v1_notes_proto_rawDesc = []byte{
|
||||
0x0a, 0x14, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31,
|
||||
0x22, 0x12, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x22, 0x37, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x6e, 0x6f, 0x74,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x22, 0x26, 0x0a,
|
||||
0x0e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x35, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x22, 0x48, 0x0a, 0x04,
|
||||
0x4e, 0x6f, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72,
|
||||
0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x72,
|
||||
0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x32, 0x9a, 0x01, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x65, 0x73,
|
||||
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x4e,
|
||||
0x6f, 0x74, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1b, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
|
||||
0x01, 0x12, 0x40, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x6e,
|
||||
0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74, 0x65, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x42, 0xbc, 0x01, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x6f, 0x74, 0x65,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x50, 0x01, 0x5a, 0x5f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73,
|
||||
0x75, 0x6e, 0x64, 0x6f, 0x77, 0x6e, 0x64, 0x65, 0x76, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x61,
|
||||
0x70, 0x69, 0x2d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x20, 0x2d, 0x20, 0x62, 0x75, 0x66, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x2f, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70,
|
||||
0x69, 0x73, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, 0x74, 0x65,
|
||||
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, 0x22, 0x12, 0x0a,
|
||||
0x10, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x22, 0x37, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x4e, 0x6f, 0x74, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x22, 0x26, 0x0a, 0x0e, 0x41, 0x64,
|
||||
0x64, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74,
|
||||
0x6c, 0x65, 0x22, 0x35, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e,
|
||||
0x6f, 0x74, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x22, 0x5d, 0x0a, 0x04, 0x4e, 0x6f, 0x74,
|
||||
0x65, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba,
|
||||
0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x05, 0x74,
|
||||
0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xba, 0x48, 0x06, 0x72,
|
||||
0x04, 0x10, 0x01, 0x18, 0x32, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
|
||||
0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x32, 0x9a, 0x01, 0x0a, 0x0c, 0x4e, 0x6f, 0x74,
|
||||
0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x09, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x1a, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x30, 0x01, 0x12, 0x40, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74, 0x65, 0x12, 0x18,
|
||||
0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x9a, 0x01, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x6f,
|
||||
0x74, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x73, 0x75, 0x6e, 0x64, 0x6f, 0x77, 0x6e, 0x64, 0x65, 0x76, 0x2f, 0x67, 0x72, 0x70, 0x63,
|
||||
0x2d, 0x61, 0x70, 0x69, 0x2d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2f, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, 0x74, 0x65,
|
||||
0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4e, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x4e, 0x6f, 0x74, 0x65,
|
||||
0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x5c, 0x56, 0x31, 0xe2,
|
||||
0x02, 0x14, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65,
|
||||
|
|
|
@ -2,7 +2,7 @@ syntax = "proto3";
|
|||
|
||||
package notes.v1;
|
||||
|
||||
option go_package = "github.com/sundowndev/grpc-api-example/proto/notes/v1";
|
||||
import "buf/validate/validate.proto";
|
||||
|
||||
service NotesService {
|
||||
rpc ListNotes(ListNotesRequest) returns (stream ListNotesResponse) {};
|
||||
|
@ -25,7 +25,7 @@ message AddNoteResponse {
|
|||
}
|
||||
|
||||
message Note {
|
||||
string id = 1;
|
||||
string title = 2;
|
||||
string id = 1 [(buf.validate.field).string.uuid = true];
|
||||
string title = 2 [(buf.validate.field).string.min_len = 1, (buf.validate.field).string.max_len = 50];
|
||||
bool archived = 3;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package server
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/bufbuild/protovalidate-go"
|
||||
"github.com/gofrs/uuid"
|
||||
notesv1 "github.com/sundowndev/grpc-api-example/proto/notes/v1"
|
||||
"sync"
|
||||
|
@ -9,14 +11,16 @@ import (
|
|||
|
||||
type NotesService struct {
|
||||
notesv1.UnimplementedNotesServiceServer
|
||||
mu *sync.RWMutex
|
||||
notes []*notesv1.Note
|
||||
mu *sync.RWMutex
|
||||
notes []*notesv1.Note
|
||||
validator *protovalidate.Validator
|
||||
}
|
||||
|
||||
func NewNotesService() *NotesService {
|
||||
func NewNotesService(v *protovalidate.Validator) *NotesService {
|
||||
return &NotesService{
|
||||
mu: &sync.RWMutex{},
|
||||
notes: make([]*notesv1.Note, 0),
|
||||
mu: &sync.RWMutex{},
|
||||
notes: make([]*notesv1.Note, 0),
|
||||
validator: v,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +48,10 @@ func (s *NotesService) AddNote(_ context.Context, req *notesv1.AddNoteRequest) (
|
|||
Archived: false,
|
||||
}
|
||||
|
||||
if err := s.validator.Validate(note); err != nil {
|
||||
return nil, fmt.Errorf("validation failed: %v", err)
|
||||
}
|
||||
|
||||
s.notes = append(s.notes, note)
|
||||
|
||||
return ¬esv1.AddNoteResponse{
|
||||
|
|
|
@ -7,14 +7,19 @@ import (
|
|||
notesv1 "github.com/sundowndev/grpc-api-example/proto/notes/v1"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/grpc/test/bufconn"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func newTestServer() (*Server, *grpc.ClientConn, error) {
|
||||
srv := NewServer(insecure.NewCredentials())
|
||||
srv, err := NewServer(insecure.NewCredentials())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
buffer := 101024 * 1024
|
||||
lis := bufconn.Listen(buffer)
|
||||
srv.listener = lis
|
||||
|
@ -36,8 +41,9 @@ func newTestServer() (*Server, *grpc.ClientConn, error) {
|
|||
|
||||
func TestNotesService_ListNotes(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
notes []*notesv1.Note
|
||||
name string
|
||||
notes []*notesv1.Note
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "test with no notes",
|
||||
|
@ -51,6 +57,20 @@ func TestNotesService_ListNotes(t *testing.T) {
|
|||
{Title: "note 3", Archived: false},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "test with min_len validation error",
|
||||
notes: []*notesv1.Note{
|
||||
{Title: "", Archived: false},
|
||||
},
|
||||
wantErr: "validation failed: validation error:\n - title: value length must be at least 1 characters [string.min_len]",
|
||||
},
|
||||
{
|
||||
name: "test with max_len validation error",
|
||||
notes: []*notesv1.Note{
|
||||
{Title: "this is a super long note title that can trigger a validation error", Archived: false},
|
||||
},
|
||||
wantErr: "validation failed: validation error:\n - title: value length must be at most 50 characters [string.max_len]",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range testcases {
|
||||
|
@ -65,8 +85,17 @@ func TestNotesService_ListNotes(t *testing.T) {
|
|||
|
||||
for _, note := range tt.notes {
|
||||
_, err := client.AddNote(context.Background(), ¬esv1.AddNoteRequest{Title: note.Title})
|
||||
if err != nil {
|
||||
if err != nil && tt.wantErr == "" {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
// Retrieve the status from the rpc error
|
||||
s, ok := status.FromError(err)
|
||||
if ok {
|
||||
assert.Equal(t, tt.wantErr, s.Message())
|
||||
} else {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package server
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/bufbuild/protovalidate-go"
|
||||
notesv1 "github.com/sundowndev/grpc-api-example/proto/notes/v1"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
@ -14,16 +15,22 @@ type Server struct {
|
|||
grpcSrv *grpc.Server
|
||||
}
|
||||
|
||||
func NewServer(c credentials.TransportCredentials) *Server {
|
||||
func NewServer(c credentials.TransportCredentials) (*Server, error) {
|
||||
s := grpc.NewServer(
|
||||
grpc.Creds(c),
|
||||
)
|
||||
srv := &Server{
|
||||
grpcSrv: s,
|
||||
}
|
||||
srv.registerServices()
|
||||
|
||||
return srv
|
||||
v, err := protovalidate.New()
|
||||
if err != nil {
|
||||
return srv, fmt.Errorf("failed to initialize validator: %v", err)
|
||||
}
|
||||
|
||||
srv.registerServices(v)
|
||||
|
||||
return srv, nil
|
||||
}
|
||||
|
||||
func (s *Server) Listen(addr string) error {
|
||||
|
@ -46,6 +53,6 @@ func (s *Server) Close() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) registerServices() {
|
||||
notesv1.RegisterNotesServiceServer(s.grpcSrv, NewNotesService())
|
||||
func (s *Server) registerServices(v *protovalidate.Validator) {
|
||||
notesv1.RegisterNotesServiceServer(s.grpcSrv, NewNotesService(v))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue