Chain custom GRPC client interceptors/DialOptions

120 views Asked by At

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?

1

There are 1 answers

4
DazWilkin On BEST ANSWER

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)
    }
}