#NestJS TCP microservice MessagePattern doesn't work

9 messages · Page 1 of 1 (latest)

pseudo laurel
#

I am trying to connect my api gateway to microservice using TCP, @plucky burrowtPattern() messages work fine, but @MessagePattern() messages don't respond to my requests

steady cosmos
#

What is your setup and what have you tried?

pseudo laurel
pseudo laurel
# steady cosmos What is your setup and what have you tried?

main.ts

async function bootstrap() {
    const app = await NestFactory.create<NestExpressApplication>(AppModule);
    const configService = app.get(ConfigService);

    const PORT = configService.get<number>('PORT') || 3000;
    const MICROSERVICE_PORT =
        configService.get<number>('MICROSERVICES_PORT') || 4000;    
    app.connectMicroservice<MicroserviceOptions>({
        transport: Transport.TCP,
        options: {
             host: '127.0.0.1',
             port: MICROSERVICE_PORT
        }
    });

    await app.startAllMicroservices();
    await app.listen(PORT);

module.ts ( from where I send messages ) (another application)

    import { Module } from '@nestjs/common';
import { ClientsModule } from '@nestjs/microservices';
import { Transport } from '@nestjs/microservices/enums';
import { KingController } from './king.controller';
import { KingServiceProvider } from './providers/king.service.provider';

@Module({
    controllers: [Controller],
    providers: [ServiceProvider],
    imports: [
        ClientsModule.register([
            {
                name: 'MAIN_BACKEND',
                transport: Transport.TCP
                options: {
                    host: '127.0.0.1',
                    port: 4000
                }
            }
        ])
    ]
})
export class Module {}

steady cosmos
#

That looks like a pretty standard setup. What does the sending and receiving code look like? What exactly does not work? Does the remote call reach the other service at all?

pseudo laurel
#

Sending code

async approveKing(kingId: string): Promise<void> {
        this.client.send<void, string>('approveKing', kingId);
    }

Receiving code

@MessagePattern('approveKing', Transport.TCP)
    async approveKing() {
        console.log('approving');
    }
steady cosmos
#

Right, so the problem is that the send call returns an Observable. Observables don't get triggered unless something subscribes to them (I recommend reading the RxJS documenetation, they explain it nicely) - to actually make the call, you need something to listen to the observable, the common approach, if the remote call returns only a single thing is to use firstValueFrom.

async approveKing(kingId: string): Promise<void> {
    const result = await lastValueFrom(this.client.send<void, string>('approveKing', kingId));
}
#

to just trigger the observable without waiting for the result, you can use

this.client.send<void, string>('approveKing', kingId).subscribe()