【问题标题】:Format request before send by ClientProxyClientProxy 发送前格式化请求
【发布时间】:2022-01-24 19:26:57
【问题描述】:

我使用微服务和 RabbitMQ 作为传输器。我的微服务相互通信,因此其中一个可以向另一个发送消息。我使用以下方式发送消息:

await this.client.send(SOME_COMMAND, obj).toPromise();

现在我需要在一个地方对我发送到任何微服务的所有请求中的对象进行格式化。比如添加reqId,或者序列化Map。有可能吗?

【问题讨论】:

  • 你想要interceptor 吗?
  • 不。 Interceptor 处理收入请求,例如,可用于格式化答案。在我的情况下,我需要在任何代码位置格式化由微服务本身发起的请求
  • 我认为如果您使用的是@nestjs/microservices 模块,那么您将无法像这里描述的那样做到这一点docs.nestjs.com/microservices/custom-transport#client-proxy
  • 最好的解决方案是创建您的自定义clientProxy
  • 请注意,拦截器不仅仅用于请求,您可以对controllers中的方法的输入/输出进行绑定

标签: microservices nestjs


【解决方案1】:

1. 每个控制器解决方案。为简单起见,我删除了处理程序部分:

@Controller()
export class AppController {
  constructor(@Inject('MATH_SERVICE') private client: ClientProxy) {
     let send = client.send.bind(client);
     client.send = function (pattern, payload) {
      
       return send(pattern, { payload, systemWideProp: ""})
    }
  }
  sum() {
    this.client.send(COMMAND, obj)
  }
}

2. 这可以作为provider 使用rabbitmq 客户端服务将其注入到您想要的每个控制器上:

custom-client-proxy.ts

import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';

@Injectable()
export class CustomClientProxy {
    constructor(@Inject('MATH_SERVICE') private client: ClientProxy) { }
    send(pattern, payload) {
        // payload and pattern manipulations such as: 
        // payload.say = "Hi";
        // const scopePattern = { cmd: `${pattern.cmd}_dev` };
        return this.client.send(pattern, payload)
    }
}

app.module.ts

import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CustomClientProxy } from './custom-client-proxy';

@Module({
  imports: [ClientsModule.register([{
    name: 'MATH_SERVICE',
    transport: Transport.RMQ,
    options: {
      urls: ['amqp://localhost:5672'],
      queue: 'math_queue'
    },
  }])],
  controllers: [AppController],
  providers: [AppService, CustomClientProxy],
  exports: [CustomClientProxy] // export here for other modules of your app
})
export class AppModule { }

app.controller.ts 还有您在应用程序模块下导入的任何控制器

@Controller()
export class AppController {
  constructor(private client: CustomClientProxy) {}
  sum() {
    this.client.send(COMMAND, obj)
  }

}

3.当您需要将此功能用于多个queue时:


// custom-client-proxy.ts

@Injectable()
export class CustomClientProxy {
    constructor() { }
    send(client: ClientProxy, pattern, payload) {
        // payload and pattern manipulations such as: 
        // payload.say = "Hi";
        // const scopePattern = { cmd: `${pattern.cmd}_dev` };
        return client.send(pattern, payload)
    }
}

// app.module.ts
@Module({
  imports: [ClientsModule.register([{
    name: 'MATH_SERVICE',
    transport: Transport.RMQ,
    options: {
      urls: ['amqp://localhost:5672'],
      queue: 'math_queue'
    },
  },
  {
    name: 'MESSAGE_SERVICE',
    transport: Transport.RMQ,
    options: {
      urls: ['amqp://localhost:5672'],
      queue: 'message_queue',
    },
  }])],
  controllers: [AppController],
  providers: [AppService, CustomClientProxy],
  exports: [CustomClientProxy]
})
export class AppModule { }

// app.controller.ts
@Controller()
export class AppController {

  constructor(
    @Inject('MATH_SERVICE') private mathClient: ClientProxy,
    @Inject('MESSAGE_SERVICE') private messageClient: ClientProxy,
    private client: CustomClientProxy) {}

  
  sum(a) {
    return this.client.sendTo(this.mathClient, pattern, payload);
  }
}

【讨论】:

  • 这行得通,但为什么不创建一个可以重复使用的包装类,在将数据传递给send 方法之前进行格式化?该类将注入 ClientProxy,现在注入此包装器的任何内容都将获得相同的格式,而无需重新分配 send 方法本身
  • @JayMcDoniel 这将是最好的,所以我正在努力将其作为一项新服务,可以在nestjs 服务中的任何地方使用
  • 类似handlePayload = (payload) => { // manipulate custom props or any serialization return newPayload }
  • 在您的示例中,令牌(服务名称)是硬编码的。
  • 第三种解决方案让您可以选择使用 customProxy 进行多种服务使用,而无需创建新服务,但第 4 种解决方案是在导入每个队列模块时用 customProxy 包装它们
【解决方案2】:

答案很简单:你需要将自定义的Serializer 传递给ClientProviderOptions,然后你就可以在那里实现一切

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多