Node.js gRPC calls and Promises

D

Domantas Jurkus

Guest
I was connecting a gRPC service with my node service and ran into an issue that i wanted to document for future sake.

The problem​


I have a controller that looks like this:


Code:
export class MyController {
  static getItem = async (_req: Request, res: Response): Promise<void> => {
    const data = await myService.getItem();

    console.log('controller: ', data);

    res.status(200).json(data);
  };
}

My service looks like this:


Code:
export class IstService {
  // ... setup stuff

  getItem = async () => {
    await this.grpcClient.GetItem(
      { item_id: 'item-1234' },
      (err: any, response: Record<string, unknown>) => {
        if (err) {
          console.error(err);
          return;
        }
        console.log('service:', JSON.stringify(response));

        return response;
      }
    );
  };
}

When I call the controller, the log order is:


Code:
apps/server start:dev: [1] controller: undefined
apps/server start:dev: [1] service: {"id": "item-1234", "foo": "bar"}

Uh oh, that's not what I want. While I have an await before myService.getItem(), the controller still finishes execution first before the gRPC call finishes.

The solution​


The solution to this problem is to wrap the service gRPC call into a new Promise:


Code:
export class IstService {
  // ... setup stuff

  getItem = async () => {
    return new Promise((resolve, reject) => {
      this.grpcClient.GetItem(
        { item_id: 'item-1234' },
        (err: any, response: Record<string, unknown>) => {
          if (err) {
            reject(err);
            return;
          }
          console.log('service:', JSON.stringify(response));

          resolve(response);
        }
      );
    });
  };
}

The main issue here is that this.grpcClient.GetItem does not use the async/await API - it uses the traditional callback pattern, where you essentially have to nest your code into the callback function.

JavaScript/TypeScript does not stop you from putting await on places where it does not make sense (would be nice is TypeScript had some automatic warning for pointless cases like these):


Code:
await console.log("just weird")

Continue reading...
 


Join 𝕋𝕄𝕋 on Telegram
Channel PREVIEW:
Back
Top