-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't detect MethodOptions #404
Comments
Hi, @majst01. Unfortunately, the grpcreflect package is written to use the gRPC Go runtime API. So it will not be helpful when using Connect. But there is luckily a way to do what you are trying to do, now that reflection/descriptor support has been added to the core Protobuf Go runtime API. A Connect server has no abstraction like a "server" or "service registrar". Instead it just generates HTTP handlers that you add to your own For a particular service, you can get the service's or methods' options via this code: // import "google.golang.org/protobuf/reflect/protoreflect"
// import "google.golang.org/protobuf/reflect/protoregistry"
// import "google.golang.org/protobuf/types/descriptorpb"
descriptor, err := protoregistry.GlobalFiles.FindDescriptorByName("acme.user.v1.UserService")
if err != nil { return err }
userSvcDesc := descriptor.(protoreflect.ServiceDescriptor)
// inspect service options
userSvcOpts := userSvcDesc.Options().(*descriptorpb.ServiceOptions)
// inspect method options
for i := 0; i < userSvcDesc.Methods().Len(); i++ {
methodDesc := userSvcDesc.Methods().Get(i)
methodOpts := methodDesc.Options().(*descriptorpb.MethodOptions)
} An improvement in the generated code for Connect would be to add exported constants with these service names. That way you don't have to hard-code the strings in your program; if the service name is changed, the program is not broken (though that is not a backwards-compatible change), and if the service is moved to a different package, there is a compile error instead of runtime error (though, again, that is not a backwards-compatible change). This would also improve the use of server reflection, which also currently requires hard-coding service names. |
Hi @jhump thanks for your explanation, meanwhile i managed to implement it somehow with the help of I will try your proposed way if i am able to get the types of the MethodOptions this way. I tried this: visibilities := proto.GetExtension(methodOpts, v1.E_Visibility).([]v1.Visibility) But it always complained that |
There are already generated constants for this! No need for hard-coded string literals anywhere. |
Oh, nice! Now that I re-read the README in connect-grpcreflect-go, I see there's a comment about it. So I just needed to read it more thoroughly. Mea culpa. |
Thanks for the support. |
in my case, i use the following code to get it
package middleware
import (
permissionv1 "permission/v1"
"connectrpc.com/connect"
)
func NewUserAuthInterceptor() connect.UnaryInterceptorFunc {
interceptor := func(next connect.UnaryFunc) connect.UnaryFunc {
return func(
ctx context.Context,
req connect.AnyRequest,
) (connect.AnyResponse, error) {
methodDesc, ok := req.Spec().Schema.(protoreflect.MethodDescriptor)
if !ok {
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("expected protoreflect.MethodDescriptor got %T", req.Spec().Schema))
}
var adminRequired bool
ext, ok := proto.GetExtension(methodDesc.Options(), permissionv1.E_Permission).(string)
if ok && ext == "admin" {
adminRequired = true
}
fmt.Println(adminRequired)
...
return next(ctx, req)
}
}
return interceptor
} |
@solarhell, thanks for posting that. That is indeed the best way to do this now. The |
@jhump I can help add the complete code to the examples repo, as this usage is very common. |
I am currently in the process of migrating an existing grpc api server to connect-go. Went smoothly so far, great work !
I am actually stuck at one point, in the current implementation i detect the specified MethodOptions per service and construct ACL Rules from them.
Example Proto
Then i use @jhump "github.com/jhump/protoreflect/grpcreflect" to load the ServiceDescriptors and iterate through.
This requires a grpc.Server instance which is not available anymore.
Any hints howto get access to the MethodOptions with a connect-go implementation are welcome.
The text was updated successfully, but these errors were encountered: