NestJS GRPC Error: call.sendMetadata is not a function

1.1k Views Asked by At

I'm trying to send a metadata from the server side gprc using NestJS framework. On the official NestJS guide here: it shows a example of doing the server side grpc metadata:

@Controller()
export class HeroesService {
    @GrpcMethod()
    findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any>): Hero {
        const serverMetadata = new Metadata();
        const items = [
          { id: 1, name: 'John' },
          { id: 2, name: 'Doe' },
        ];
    
        serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
        call.sendMetadata(serverMetadata);
    
        return items.find(({ id }) => id === data.id);
    }
}

On my code, I wrote a similar code:

@GrpcMethod('ClinicService', 'GetCustomerClinicNames')
async GetCustomerClinicNames_GRPC(data: CustomerClinicID, call:ServerUnaryCall<Any,Any>) {
    const metadata = new Metadata();
    const result = await this.clinicService.GetClinicName(Number(data.customer_id));
    console.log(result);
    metadata.add('context', "Jello")
    call.sendMetadata(metadata)
    return { response: result};
}

However, it gives me an error says:

[Nest] 53188  - 04/06/2022, 5:17:50 PM   ERROR [RpcExceptionsHandler] call.sendMetadata is not a function
TypeError: call.sendMetadata is not a function
    at ClinicController.GetCustomerClinicNames_GRPC (C:\Users\Vibrant\Desktop\core-samples\src\clinic\clinic.controller.ts:118:10)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at C:\Users\Vibrant\Desktop\core-samples\node_modules\@nestjs\microservices\context\rpc-proxy.js:11:32

But I think the .sendMetadata is indeed a function. Where am I wrong about this?

For the sendMetadata Function, it is defined as:

export declare type ServerSurfaceCall = {
    cancelled: boolean;
    readonly metadata: Metadata;
    getPeer(): string;
    sendMetadata(responseMetadata: Metadata): void;
    getDeadline(): Deadline;
} & EventEmitter;

export declare type ServerUnaryCall<RequestType, ResponseType> = ServerSurfaceCall & {
    request: RequestType;
};
1

There are 1 best solutions below

3
On BEST ANSWER

So apparently you need to keep the metadata parameter in your async GetCustomerClinicNames_GRPC. I tried with and without and it only worked when I had it.

so for example, I tried:

@GrpcMethod('HeroesService', 'FindOne')
findOne(data: any, call: ServerUnaryCall<any, any>): any

and that didn't work, then I tried:

@GrpcMethod('HeroesService', 'FindOne')
findOne(data: any, _metadata: Metadata, call: ServerUnaryCall<any, any>): any

and it worked by doing something like:

@GrpcMethod('HeroesService', 'FindOne')
findOne(data: any, _metadata: Metadata, call: ServerUnaryCall<any, any>): any {
    const items = [
        { id: 1, name: 'John' },
        { id: 2, name: 'Doe' },
    ];
    
    const metadata = new Metadata();
    metadata.add('context', 'Jello');
    call.sendMetadata(metadata);

    return items.find(({ id }) => id === data.id);
}

I'm not sure why though, since we are using named arguments.