ClientProxy 发送前格式化请求

Format request before send by ClientProxy

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

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

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

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 客户端服务将其注入每个控制器:

自定义客户端-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);
  }
}

答案很简单:您需要将自定义 Serializer 传递给 ClientProviderOptions,您可以在那里实现所有内容