nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
67.28k stars 7.59k forks source link

Can't send metadata with NestJS GRPC #1897

Closed AnthonySendra closed 3 years ago

AnthonySendra commented 5 years ago

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

When I create a microservice GRPC server with NestJS, I can't send metadata in my response.

Expected behavior

I want to be able to send headers to my client.

Minimal reproduction of the problem with instructions

@GrpcMethod('AuthReadService', 'SignIn')
  async signIn(
    data: my.api.auth.SignInRequest,
  ): Promise<any> {
      const response = await this.authService.signIn(data.email, data.password);
      const metadata = new grpc.Metadata();
      metadata.set(
        'Set-Cookie',
        `jwt=${response.jwt}; Expires=${response.expiresIn}; HttpOnly`,
      );

      // How can I send metadata to the client?
  }

What is the motivation / use case for changing the behavior?

I need to find a way to send the header Set-Cookie for authentication

Environment


Nest version: 6.0.0


For Tooling issues:
- Node version: v10.15.0  
- Platform:  Mac 

Others:

I'm using GRPC/Protobuf from browser with envoy proxy.
AnthonySendra commented 5 years ago

More context:

We call the callback with only two parameters here: https://github.com/nestjs/nest/blob/master/packages/microservices/server/server-grpc.ts#L136

In my case, this callback comes from here: https://github.com/grpc/grpc-node/blob/master/packages/grpc-native-core/src/server.js#L590

And call the function sendUnaryResponse defined here: https://github.com/grpc/grpc-node/blob/master/packages/grpc-native-core/src/server.js#L83

This function take metadata in argument but we don't pass it in the arguments of the callback.

I tried to update the function like:

createUnaryServiceMethod(methodHandler) {
    return async (call, callback) => {
      console.log('createUnaryServiceMethod', callback);
      const handler = methodHandler(call.request, call.metadata);
      this.transformToObservable(await handler).subscribe(
        data => {
          if (data.response && data.metadata) {
            callback(null, data.response, data.metadata);
          } else {
            callback(null, data);
          }
        },
        err => callback(err),
      );
    };
  }

But now I have an error in my browser. The metadata is not sent in the headers but in body

didin1453fatih commented 4 years ago

@kamilmysliwiec how about this issue...? Can you help me. I need send metadata response to client. I need to attach version of application service. I need attach to anywhere but not in body data of gRPC.

kamilmysliwiec commented 3 years ago

See https://github.com/nestjs/nest/pull/5143 for instructions. This PR was merged and released as 7.5.0