How to use gRPC reflection in a browser client without Node.js?

106 Views Asked by At

I would like my React.js web application to be able to connect to my gRPC server implementing the gRPC Server Reflection Protocol.

Using gRPC reflection would allow the web app to discover and use methods dynamically instead of having to import proto files.

I took a look at some libraries like grpc-js-reflection-api-client and gprc-reflection-js, but these assume a Node.js runtime through their dependency on @grpc/grpc-js, and it doesn't seem feasible to run them from a browser application.

Is there another way to use gRPC reflection, using libraries like grpc-web perhaps?

Here is a simple example along the lines of what I would like to do (code snippet from grpc-js-reflection-api-client):

const { GrpcReflection } = require('grpc-js-reflection-client');
const grpc =  require('@grpc/grpc-js');

function getChannelCredentials() {
    return grpc.ChannelCredentials.createSsl();
}

(async()=> {
    const client = new GrpcReflection(
        'grpcb.in:9001',
        getChannelCredentials(),
    );
    console.log(await client.listServices());
})();
1

There are 1 best solutions below

1
Richard Belleville On

Unfortunately, gRPC Web is not capable of supporting the standard gRPC reflection protocol. The issue is that reflection is a bidirectional streaming RPC and gRPC web does not support bidirectional streaming due to missing HTTP/2 trailer support in most browser implementations of HTTP/2.

The reason that this RPC is defined to use bidi streaming is that it ensures all type information comes from a single backend server and when frontend by a load balancers, you will not have situations where inconsistent type information is returned by disagreeing servers.

If you're willing to write your own reflection server implementation, you could do so as a server-side streaming RPC, which is supported by gRPC Web. Of course, you'd either need to ensure sticky sessions with your load balancer or ensure that all backend servers agreed on all type information.

This would also mean that you could not rely on any existing reflection client libraries. Regardless, you're definitely going off-road here.