<p>I've got several gRPC microservices deployed via Istio in my k8s pod behind a gateway that handles the routing for web clients.  Things work great when I need to send an RPC from client (browser) to any of these services.</p>
<p>I'm now at the point where I want to call service A from service B directly.  How do I go about doing that?</p>
<p>Code for how both the servers are instantiated:</p>
<pre><code>  const server = new grpc.Server();
  server.addService(MyService, new MyServiceImpl());
  server.bindAsync(`0.0.0.0:${PORT_A}`, grpc.ServerCredentials.createInsecure(), () =&gt; {
    server.start();
  });
</code></pre>
<p>A Service Account is being used with GOOGLE_APPLICATION_CREDENTIALS and a secret in my deployment YAML.</p>
<p>To call service A from service B, I was thinking the code in service B would look something like:</p>
<pre><code>    const serviceAClient: MyServiceClient = new MyServiceClient(`0.0.0.0:${PORT_A}`, creds);
    const req = new SomeRpcRequest()...;
    serviceAClient.someRpc(req, (err: grpc.ServiceError, response: SomeRpcResponse) =&gt; {
      // yay!
    });
</code></pre>
<p>Is that naive?  One thing I'm not sure about is the creds that I need to pass when instantiating the client.  I get complaints that I need to pass ChannelCredentials, but every mechanism I've tried to create those creds has not worked.</p>
<p>Another thing I'm realizing is that 0.0.0.0 can't be correct because each service is in its own container paired with a sidecar proxy... so how do I route RPCs properly and attach proper creds?</p>
<p>I'm trying to construct the creds this way:</p>
<pre><code>let callCreds = grpc.CallCredentials.createFromGoogleCredential(myOauthClient);
let channelCreds = grpc.ChannelCredentials.createSsl().compose(callCreds);
const serviceAClient = new MyServiceClient(`0.0.0.0:${PORT_A}`, channcelCreds);

</code></pre>
<p>and I'm mysteriously getting the following error stack:</p>
<pre><code>UnhandledPromiseRejectionWarning: TypeError: Channel credentials must be a ChannelCredentials object
    at new ChannelImplementation (/bish/proto/activities/node_modules/@grpc/grpc-js/build/src/channel.js:69:19)
    at new Client (/bish/proto/activities/node_modules/@grpc/grpc-js/build/src/client.js:58:36)
    at new ServiceClientImpl (/bish/proto/activities/node_modules/@grpc/grpc-js/build/src/make-client.js:58:5)
    at PresenceService.&lt;anonymous&gt; (/bish/src/servers/presence/dist/presence.js:348:44)
    at step (/bish/src/servers/presence/dist/presence.js:33:23)
    at Object.next (/bish/src/servers/presence/dist/presence.js:14:53)
    at fulfilled (/bish/src/servers/presence/dist/presence.js:5:58)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
</code></pre>
<p>Which is odd because channelCreds is a ComposedChannelCredentialsImpl which, in fact, extends ChannelCredentials</p>

codedread
<p>Ok, at least the root cause of the &quot;Channel credentials must be a ChannelCredentials object&quot; error is now known.  I'm developing node packages side-by-side as symlinks and each of the dependencies has their own copy of grpc-js in it.</p>
<p><a href="https://github.com/npm/npm/issues/7742#issuecomment-257186653" rel="nofollow noreferrer">https://github.com/npm/npm/issues/7742#issuecomment-257186653</a></p>
