Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Cannot reach gRPC services via NestJS

I have a simple microservice app using NestJS. It is intended for Google Cloud Run (GCR). In consists of:
  • Gateway
  • Microservice A

The Gateway is running like this:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const configService = app.get(ConfigService<EnvironmentVariables>);
  const PORT = configService.get<number>('PORT');
  await app.listen(PORT, () => {
    console.log(`App gateway is running on port ${PORT}`);
  });
}

Microservices are handled by:

@Module({
  imports: [
    ClientsModule.registerAsync({
      clients: [
        {
          name: Microservice.CONTENT,
          imports: [ConfigModule],
          inject: [ConfigService],
          useFactory: (config: ConfigService<EnvironmentVariables>) => {
            return {
              transport: Transport.GRPC,
              options: {
                url: config.get<string>('MS_CONTENT_URL'),
                package: CONTENT_PACKAGE_NAME,
                protoPath: join(PROTO_FOLDER_PATH, 'content.proto'),
              },
            };
          },
        },
      ],
    }),
  ],
  exports: [ClientsModule],
})
export class MicroserviceClientModule {}

Microservice A inits as:

async function bootstrap() {
  const PORT = parseInt(process.env.PORT) || 5000;
  const logger = new Logger();

  const microserviceOptions: MicroserviceOptions = {
    transport: Transport.GRPC,
    options: {
      url: `0.0.0.0:${PORT}`,
      package: CONTENT_PACKAGE_NAME,
      protoPath: join(PROTO_FOLDER_PATH, 'content.proto'),
    },
  };
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    ContentModule,
    microserviceOptions,
  );
  await app.listen();
  logger.debug(`Started GRPC server on ${microserviceOptions.options.url}`);
}

The deployment to GCR happens with no problem. As the result, there is a GCR service for the gateway and a service for the microservice. After the first (initial) deployment creating a service, I manually set up the env vars for the services. Amongs the env vars, there is MS_CONTENT_URL which tells the Gateway where the microservice is running. in the local env, it is just, for example localhost:5000. But once it is deployed to GCR, it becomes something I do not understand. As I see it, I have to use the url given by GCR after the service deployment, such as https://my-microservice-12345asbcdef-ey.a.run.app. When calling it without protocol and no port (meaning my-microservice-12345asbcdef-ey.a.run.app), it is 1 CANCELLED: Call cancelled. If I enable the http/2 option, any request to the gateway fails with upstream connect error or disconnect/reset before headers. reset reason: protocol error. When I make a gRPC call via Postman directly to the microservice, it works. But he porblem remains with a case when the call is done via the gateway to a microservice, or by a microservice to another microservice: it says "1 CANCELLED: Call cancelled"

No VPC or anything like that was defined. Locally everything is working and with a similar request I do retrieve a simple JSON response. I also was thinking that I need to do something in the app code itself to somehow "activate" http/2 support.

All the project services have Allow unauthenticated.

Solved Solved
0 1 579
1 ACCEPTED SOLUTION

Found a solution: when registering clients, this line must be added:

credentials.createSsl()

View solution in original post

1 REPLY 1

Found a solution: when registering clients, this line must be added:

credentials.createSsl()