
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@nam088/nestjs-grpc
Advanced tools
A modern gRPC client library for NestJS with full streaming support and smart retry strategies
A modern, production-ready gRPC client library for NestJS with full streaming support, smart retry strategies, and comprehensive TypeScript types.
npm install @nam088/nestjs-grpc
// app.module.ts
import { GrpcClientModule } from '@nam088/nestjs-grpc';
@Module({
imports: [
GrpcClientModule.forRoot({
services: [{
protoPath: './proto/user.proto',
package: 'user',
serviceName: 'UserService',
url: 'localhost:50051'
}],
retry: {
maxAttempts: 3,
initialBackoff: 1000,
retryableCodes: [grpc.status.UNAVAILABLE]
},
logLevel: 'DEBUG'
})
]
})
export class AppModule {}
// user.service.ts
@Injectable()
export class UserService {
constructor(private grpc: GrpcClientService) {}
getUser(id: string) {
return this.grpc.call({
package: 'user',
service: 'UserService',
method: 'GetUser',
request: { id }
});
}
}
this.grpc.call({
package: 'user',
service: 'UserService',
method: 'GetUser',
request: { id: '123' },
timeout: 5000 // Optional timeout in ms
}).subscribe(user => console.log(user));
this.grpc.call({ ... }).pipe(
timeout(5000),
map(user => user.email),
catchError(err => of(null))
).subscribe();
this.grpc.callServerStream({
package: 'chat',
service: 'ChatService',
method: 'StreamMessages',
request: { roomId: 'room1' }
}).subscribe(message => console.log(message));
const { stream, response } = this.grpc.callClientStream({
package: 'upload',
service: 'FileService',
method: 'UploadFile'
});
// Send data
stream.next({ chunk: data1 });
stream.next({ chunk: data2 });
stream.complete();
// Get response
response.subscribe(result => console.log(result));
const { stream, response } = this.grpc.callBidiStream({
package: 'chat',
service: 'ChatService',
method: 'Chat'
});
// Send and receive simultaneously
stream.next({ text: 'Hello' });
response.subscribe(msg => console.log(msg));
import { RetryStrategy } from '@nam088/nestjs-grpc';
this.grpc.call({ ... }).pipe(
RetryStrategy.retry({
maxAttempts: 3,
backoffStrategy: 'exponential',
retryableCodes: [grpc.status.UNAVAILABLE],
initialBackoff: 1000,
maxBackoff: 5000,
backoffMultiplier: 2,
enableJitter: true
})
).subscribe();
// app.module.ts
GrpcClientModule.forRoot({
services: [...],
interceptors: [LoggingInterceptor, MetricsInterceptor]
})
// Custom interceptor
@Injectable()
export class MetricsInterceptor implements GrpcInterceptor {
intercept(options, next) {
const start = Date.now();
return next().pipe(
tap(() => this.recordMetric(Date.now() - start))
);
}
}
@Catch(GrpcException)
export class GrpcExceptionFilter implements ExceptionFilter {
catch(exception: GrpcException, host: ArgumentsHost) {
const response = host.switchToHttp().getResponse();
response.status(exception.getStatus()).json({
error: exception.details,
code: exception.code
});
}
}
GrpcClientModule.forRoot({
services: GrpcServiceConfig[],
interceptors?: GrpcInterceptor[],
isGlobal?: boolean,
retry?: RetryConfig,
logLevel?: 'DEBUG' | 'INFO' | 'WARN' | 'ERROR'
})
| Method | Description | Returns |
|---|---|---|
call() | Unary call | Observable<TResponse> |
callServerStream() | Server streaming | Observable<TResponse> |
callClientStream() | Client streaming | { stream, response } |
callBidiStream() | Bidirectional | { stream, response } |
RetryStrategy.retry({
maxAttempts?: number, // Default: 3
initialBackoff?: number, // Default: 1000
maxBackoff?: number, // Default: 5000
backoffStrategy?: 'exponential' | 'linear' | 'fixed',
backoffMultiplier?: number, // Default: 2
retryableCodes?: grpc.status[],
enableJitter?: boolean // Default: true
})
GrpcClientModule.forRoot({
services: [{
protoPath: './proto/user.proto',
package: 'user',
serviceName: 'UserService',
url: 'localhost:50051'
}]
})
GrpcClientModule.forRoot({
services: [
{
protoPath: './proto/user.proto',
package: 'user',
serviceName: 'UserService',
url: 'localhost:50051'
},
{
protoPath: './proto/order.proto',
package: 'order',
serviceName: 'OrderService',
url: 'localhost:50052'
}
],
isGlobal: true
})
import * as grpc from '@grpc/grpc-js';
GrpcClientModule.forRoot({
services: [{
protoPath: './proto/user.proto',
package: 'user',
serviceName: 'UserService',
url: 'api.example.com:443',
credentials: grpc.credentials.createSsl()
}]
})
describe('UserService', () => {
let service: UserService;
let grpcClient: GrpcClientService;
beforeEach(async () => {
const module = await Test.createTestingModule({
imports: [GrpcClientModule.forRoot({ services: [...] })],
providers: [UserService]
}).compile();
service = module.get<UserService>(UserService);
grpcClient = module.get<GrpcClientService>(GrpcClientService);
});
it('should get user', async () => {
const result = await lastValueFrom(service.getUser('123'));
expect(result).toBeDefined();
});
});
// Before
const client = new UserServiceClient('localhost:50051');
client.getUser({ id: '123' }, (err, response) => {
if (err) throw err;
console.log(response);
});
// After
this.grpc.call({
package: 'user',
service: 'UserService',
method: 'GetUser',
request: { id: '123' }
}).subscribe({
next: response => console.log(response),
error: err => console.error(err)
});
Use Retry for Production
this.grpc.call({ ... }).pipe(
RetryStrategy.retry({ maxAttempts: 3 })
)
Add Timeouts
this.grpc.call({ ... }).pipe(timeout(5000))
Handle Errors Gracefully
this.grpc.call({ ... }).pipe(
catchError(err => {
this.logger.error(err);
return of(defaultValue);
})
)
Use Interceptors for Cross-Cutting Concerns
// Logging, metrics, tracing
GrpcClientModule.forRoot({
interceptors: [LoggingInterceptor, MetricsInterceptor]
})
MIT © 2025
FAQs
A modern gRPC client library for NestJS with full streaming support and smart retry strategies
We found that @nam088/nestjs-grpc demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.