Skip to main content

Microservices

Use tRPC at the edge and delegate heavy domain operations to NestJS microservices via TCP, Redis, NATS, or other transports.

Architecture

┌─────────────────────────┐
│ tRPC Gateway (Nest) │ ← public-facing, TrpcModule
│ @Router('orders') │
│ @Query() get() │──→ ClientProxy.send('orders.findById')
└─────────────────────────┘

TCP / Redis / NATS

┌─────────────────────────┐
│ Orders Microservice │ ← internal, @nestjs/microservices
│ @MessagePattern(...) │
└─────────────────────────┘

Gateway Service

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

@Injectable()
export class OrdersGatewayService {
constructor(@Inject('ORDERS_CLIENT') private readonly client: ClientProxy) {}

async findById(id: string) {
return lastValueFrom(this.client.send('orders.findById', { id }));
}
}

Gateway Router

import { Input, Query, Router } from 'nest-trpc-native';

@Router('orders')
export class OrdersRouter {
constructor(private readonly orders: OrdersGatewayService) {}

@Query()
get(@Input('id') id: string) {
return this.orders.findById(id);
}
}

Client Proxy Wiring

import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
providers: [
{
provide: 'ORDERS_CLIENT',
useFactory: () =>
ClientProxyFactory.create({
transport: Transport.TCP,
options: { host: '127.0.0.1', port: 4001 },
}),
},
OrdersGatewayService,
OrdersRouter,
],
})
export class OrdersModule {}

This keeps tRPC procedures thin while preserving Nest transport strategies for internal service boundaries.