I want to chain some DialOptions
/client-side interceptors. But for some reason only the latest of my custom interceptors will be invoked:
myOpt1 := grpc.WithUnaryInterceptor(func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
print("testInterceptor invoked")
return invoker(ctx, method, req, reply, cc, opts...)
})
myOpt2 := grpc.WithUnaryInterceptor(func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
print("testInterceptor2 invoked")
return invoker(ctx, method, req, reply, cc, opts...)
})
opts := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
myOpt1, // will be skipped
myOpt2, // will get invoked
}
conn, err := grpc.DialContext(context.Background(), "my-adress:443", opts...) // err is nil
myService := pbAugment.NewMyServiceClient(conn)
myService.MyFunction(context.Background()) // prints: testInterceptor2 invoked
I've added TransportCredentials
so I don't get an error on startup (about missing transport security).
What am I missing here?
You must chain (Client|Server) interceptors:
See grpc.WithChainUnaryInterceptor
E.g.:
func main() {
myInt1 := func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
print("testInterceptor invoked")
return invoker(ctx, method, req, reply, cc, opts...)
}
myInt2 := func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
print("testInterceptor2 invoked")
return invoker(ctx, method, req, reply, cc, opts...)
}
opts := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithChainUnaryInterceptor(
myInt1,
myInt2,
),
}
_, err := grpc.DialContext(context.Background(), "my-adress:443", opts...)
if err != nil {
log.Fatal(err)
}
}