NestJS
Microservices
HTTP
RabbitMQ
Backend Development

NestJS - Combine HTTP with RabbitMQ in microservices

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

NestJS is a progressive Node.js framework used for building efficient and scalable server-side applications. In the realm of microservices, communication between different services is pivotal. NestJS supports various communication strategies, but two powerful options are HTTP for synchronous communication and RabbitMQ for asynchronous communication. Combining these two can leverage the strengths of both synchronous and asynchronous communication, making the architecture robust and versatile.

Understanding HTTP and RabbitMQ in NestJS

HTTP is the conventional protocol for client-server communication in web applications. It operates in a request-response pattern where the client sends a request, and the server returns a response. This is typically handled in NestJS using controllers which respond to specific routes.

RabbitMQ, on the other hand, is a message broker that enables asynchronous communication. It works by sending messages that are consumed by different services at their own pace, which is ideal for decoupling application components. NestJS integrates RabbitMQ using Microservices module which abstracts away some of the complexities of direct message handling.

Setting Up NestJS with HTTP and RabbitMQ

First, ensure you have NestJS CLI installed by running:

bash
npm i -g @nestjs/cli

Create a new project:

bash
nest new nest-microservice-project

Add RabbitMQ support:

bash
npm install @nestjs/microservices amqplib amqp-connection-manager

Configuring the Hybrid Application

Set up both HTTP controllers and RabbitMQ configurations within the same application:

  1. HTTP Controller Setup
    Create a basic controller:
typescript
1   import { Controller, Get } from '@nestjs/common';
2
3   @Controller('health')
4   export class HealthController {
5       @Get()
6       check() {
7           return { status: 'up' };
8       }
9   }
  1. RabbitMQ Configuration
    Configure a microservice:
typescript
1   import { MicroserviceOptions, Transport } from '@nestjs/microservices';
2
3   // In your main.ts or wherever you bootstrap your app
4   async function bootstrap() {
5       const app = await NestFactory.create(AppModule);
6       app.connectMicroservice<MicroserviceOptions>({
7           transport: Transport.RMQ,
8           options: {
9               urls: ['amqp://localhost:5672'],
10               queue: 'main_queue',
11               queueOptions: {
12                   durable: false
13               },
14           },
15       });
16
17       await app.startAllMicroservices();
18       await app.listen(3000);
19   }
20   bootstrap();

Example: Using HTTP to Manage RabbitMQ Messages

Imagine a scenario where you receive a user creation HTTP request, and you need to communicate this update to other microservices asynchronously:

  1. Receive HTTP Request and Publish to RabbitMQ
    UsersController:
typescript
1    import { Controller, Post, Body } from '@nestjs/common';
2    import { ClientProxy, ClientProxyFactory, Transport } from '@nestjs/microservices';
3
4    @Controller('users')
5    export class UsersController {
6        private client: ClientProxy;
7
8        constructor() {
9            this.client = ClientProxyFactory.create({
10                transport: Transport.RMQ,
11                options: {
12                    urls: ['amqp://user:pass@localhost:5672'],
13                    queue: 'users_queue',
14                    queueOptions: {
15                        durable: false
16                    },
17                },
18            });
19        }
20
21        @Post()
22        async createUser(@Body() userData: { email: string; name: string }) {
23            await this.client.emit<string>('user_created', userData);
24            return { status: 'User creation message sent' };
25        }
26    }

Summary Table: Combining HTTP and RabbitMQ

Key ComponentDetailsUsage
HTTP ControllerManage incoming HTTP requestsFront-facing interactions, direct client responses
RabbitMQ PublisherSend messages asynchronouslyDecouple component communication, manage background tasks
RabbitMQ ConsumerProcess received messagesOperate independently of front-end servers, manage load effectively

Considerations

  • Error Handling: Ensure robustness by handling possible errors in message delivery or consumption. Implement retry mechanisms or dead letter exchanges.
  • Security: Secure your RabbitMQ channels and ensure that HTTP endpoints are protected using appropriate authentication and authorization mechanisms.

Conclusion

By combining HTTP and RabbitMQ in a NestJS microservices architecture, you benefit from the immediacy of HTTP and the robustness and elasticity provided by asynchronous messaging. This approach is extremely useful for building complex, high-load, and resilient service-oriented architectures.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.