'NestJS GRPC metadata no longer received by server after @grpc/grpc-js update

The package grpc is being depreciated so i have moved to @grpc/grpc-js as advised by the maintainers. Since moving to the new package NestJs no longer receives the metadata in the ExecutionContext the following code has worked fine up until the switch.

The server uses @grpc/grpc-js like so:

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { Metadata, status } from '@grpc/grpc-js';
import { RpcException } from '@nestjs/microservices';

export interface IUserDecorator {
  clientId: string;
}

export const User = createParamDecorator(
  (data, context: ExecutionContext): IUserDecorator => {
    const metadata = context.switchToRpc().getContext() as Metadata;
    const { clientid } = metadata.getMap();

    if (!clientid) {
      throw new RpcException({
        code: status.UNAUTHENTICATED,
        message: 'clientId is required',
      });
    }

    return {
      clientId: clientid.toString(),
    };
  },
);

The Client constructs metadata like so:

import * as GRPC from '@grpc/grpc-js';

const meta = new GRPC.Metadata();
meta.add("clientId", "dasd");

constructing meta data in this way produces the following object

Metadata { internalRepr: Map { 'clientid' => [Array] }, options: {} }

The server does not receive the set meta

   // console.log context.switchToRpc().getContext()

   {
        "_internal_repr": {
            "user-agent": [
                "grpc-node/1.24.4 grpc-c/8.0.0 (osx; chttp2; ganges)"
            ]
        },
        "flags": 0
    },

however when i cunstruct metadata with the old grpc package the server correctly receives metadata.

import { Metadata } from 'grpc'
const goodMets = new Metadata();
goodMets.add('clientId', 'dasd');

produces

Metadata { _internal_repr: { clientid: [Array] }, flags: 0 }

server receives

    {
        "_internal_repr": {
            "clientid": [
                "dasd"
            ],
            "user-agent": [
                "grpc-node/1.24.4 grpc-c/8.0.0 (osx; chttp2; ganges)"
            ]
        },
        "flags": 0
    },

I naively tried to add the meta as snake case (almost certain it wouldn't work, but you know ... got to try)



Solution 1:[1]

I was facing same issue. So i have upgraded nestjs@7 to nestjs@8. to make it work.

eg. if you look into metadata, user-agent is grpc-node/1.24.6 its actually coming from grpc package.

Solution 2:[2]

The change you made here wouldn't actually switch to the new grpc-js package. It just tries to use the Metadata class from grpc-js with the grpc package used internally within NestJS. NestJS would need to change its dependency on grpc to @grpc/grpc-js in order to actually switch.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Himanshu
Solution 2 murgatroid99