# Building Microservices with NestJS: A Complete Guide

## Introduction

Microservices have gained immense popularity due to their scalability, maintainability, and flexibility. NestJS, a progressive Node.js framework, provides robust tools for building microservices efficiently. In this guide, we'll explore how to build a microservices architecture with NestJS and use **NATS (NATS Messaging System)** as the communication broker.

## Why Use NestJS for Microservices?

NestJS is built with TypeScript and heavily inspired by Angular, making it a great choice for developers who prefer a structured and modular approach. Here are some benefits:

* **Built-in Microservices Support**: NestJS provides an abstraction layer for microservices.
    
* **Scalability**: Easily scales using distributed messaging.
    
* **Dependency Injection**: Helps in writing modular and testable code.
    
* **Interoperability**: Works seamlessly with multiple transport layers (NATS, Redis, Kafka, gRPC, etc.).
    

## Why Choose NATS for Microservices Communication?

NATS is a lightweight and high-performance messaging system that provides **event-driven communication**. Reasons to use NATS in NestJS:

* **Low Latency & High Throughput**
    
* **Simple & Fast Messaging**
    
* **Auto-scaling Support**
    
* **Built-in Streaming & Persistence Options**
    

## Setting Up NestJS Microservices with NATS

### Step 1: Create a NestJS Project

If you haven't already installed NestJS, install it globally:

```sh
npm install -g @nestjs/cli
```

Now, create a new NestJS project:

```sh
nest new microservices-nats
cd microservices-nats
```

### Step 2: Install Required Dependencies

To use NATS in NestJS, install the necessary packages:

```sh
npm install @nestjs/microservices nats
```

### Step 3: Create a Microservice

Create a new file **src/microservice/main.ts** for our microservice:

```typescript
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { AppModule } from '../app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
    transport: Transport.NATS,
    options: {
      servers: ['nats://localhost:4222'],
    },
  });
  await app.listen();
  console.log('Microservice is running');
}
bootstrap();
```

### Step 4: Create a Message Handler

Inside **app.service.ts**, create a message handler:

```typescript
import { Injectable } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Injectable()
export class AppService {
  @MessagePattern('greet')
  handleGreetMessage(data: string): string {
    return `Hello, ${data}!`;
  }
}
```

### Step 5: Create the API Gateway

Now, let's set up a gateway service to send messages to our microservice. Modify **src/main.ts**:

```typescript
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.connectMicroservice<MicroserviceOptions>({
    transport: Transport.NATS,
    options: {
      servers: ['nats://localhost:4222'],
    },
  });
  
  await app.startAllMicroservices();
  await app.listen(3000);
  console.log('API Gateway is running on port 3000');
}
bootstrap();
```

### Step 6: Create a Controller to Send Messages

Inside **app.controller.ts**, create an endpoint to communicate with the microservice:

```typescript
import { Controller, Get } from '@nestjs/common';
import { Client, ClientProxy, Transport } from '@nestjs/microservices';

@Controller()
export class AppController {
  @Client({
    transport: Transport.NATS,
    options: {
      servers: ['nats://localhost:4222'],
    },
  })
  private client: ClientProxy;

  @Get('greet')
  async sendMessage() {
    const response = await this.client.send('greet', 'NestJS').toPromise();
    return { message: response };
  }
}
```

## Running the Microservices

1. **Start NATS Server**
    
    ```sh
    nats-server -js
    ```
    
2. **Run the Microservice**
    
    ```sh
    npm run start:microservice
    ```
    
3. **Run the API Gateway**
    
    ```sh
    npm run start
    ```
    
4. **Test the Endpoint** Open your browser or use Postman to test the endpoint:
    
    ```plaintext
    http://localhost:3000/greet
    ```
    
    Expected response:
    
    ```json
    { "message": "Hello, NestJS!" }
    ```
    

## Conclusion

Building microservices with NestJS and NATS provides a powerful combination for scalable applications. NestJS simplifies the microservice architecture, while NATS ensures efficient and reliable messaging. With this guide, you're now ready to build and deploy your own distributed systems using NestJS and NATS!

### Next Steps

* Explore **NATS Streaming** for message persistence.
    
* Implement **gRPC** alongside NATS for hybrid communication.
    
* Use **Docker & Kubernetes** to containerize and orchestrate microservices.
    

Happy coding! 🚀
