Skip to content

API Calls

Camillalalala edited this page Nov 14, 2025 · 4 revisions

Introduction

NestJS supports two major forms of inter-service communication:

  1. HTTP-based communication (synchronous, request–response)

  2. Message-based communication using RabbitMQ or other brokers (asynchronous, event-driven)

This page summarizes the structure, inputs, and outputs of each communication type and explains how they are used in microservice architectures.


HTTP-Based Communication

HTTP communication in NestJS follows standard RESTful patterns using controllers, route decorators, and (optionally) the HttpService from @nestjs/axios for inter-service requests.


🔹Structure of HTTP Request Endpoints

HTTP routes are defined using @Controller() along with method decorators:

@Controller('users')

export class UsersController {

  @Get(':id')

  getUser(@Param('id') id: string) { ... }


  @Post()

  createUser(@Body() dto: CreateUserDto) { ... }


  @Patch(':id')

  updateUser(@Param('id') id: string, @Body() dto: UpdateUserDto) { ... }

}


Common Input Decorators

@Body() – receives JSON request data (usually validated through DTOs)
@Body() createUserDto: CreateUserDto

@Param() – extracts route parameters
@Param('id') id: string

@Query() – retrieves query-string parameters
@Query('filter') filter: string

DTOs (Data Transfer Objects) define and validate the expected shape of incoming data.


🔹Calling Other Services via HTTP

Microservices can call each other using HttpService (Axios wrapper):

const response = await firstValueFrom(

  this.httpService.get(`http://clubs-service/clubs/${name}`)

);

Examples of usage:

  • Users → Clubs Service:
    Fetch clubs via GET requests (/clubs, /clubs/:name)

  • API Gateway → Users / Clubs:
    Gateway uses Axios to orchestrate calls between microservices.

Common HTTP Methods

  • GET — Retrieve data

  • POST — Create new data

  • PATCH — Partially update existing data

  • PUT — Completely replace an existing resource

  • DELETE — Remove a resource

  • HEAD — GET without response body (headers only)

  • OPTIONS — Returns allowed HTTP methods (CORS)

  • TRACE — Echo request back (rare; often disabled)

  • CONNECT — Opens a tunnel (rare)


HTTP Responses

Controllers return standard JSON objects as responses.

🔹Status Codes

You may override default responses using:

  • @HttpCode(201)

Common examples:

  • 200 OK — successful GET

  • 201 Created — successful POST

  • 400 Bad Request

  • 404 Not Found

  • 503 Service Unavailable

🔹Exceptions for Error Handling

NestJS provides built-in exception classes:

  • BadRequestException('Invalid input') → 400 Bad Request

  • NotFoundException('User not found') → 404 Not Found

  • HttpService.SERVICE_UNAVAILABLE → 503 Service Unavailable

This allows consistent HTTP responses across services.


🔹 HTTP Response Structure

Controllers return structured JSON responses, with metadata and error handling features.

  • Response body – usually a JSON object (data, confirmation message, or error)

  • Status code – e.g., 200 OK, 201 Created, 400 Bad Request, 404 Not Found
    Headers – e.g., Content-Type: application/json, CORS headers, custom metadata

  • Cookies – optional (for session-based communication)

  • Error responses – exceptions automatically converted to JSON error objects

Example Response Configuration:

@HttpCode(201)

createUser() {

  // ...

  throw new BadRequestException('Invalid input'); // → 400 Bad Request

}


Message-Based Communication (RabbitMQ, TCP, etc.)

Unlike HTTP, message-based communication in NestJS is asynchronous.
It relies on message patterns and payloads rather than HTTP methods or routes.
RabbitMQ is a popular broker used for this communication style.


🔹 Overview

  • Messages are plain JavaScript objects or DTOs passed through a message broker.

  • Communication happens through commands and payloads, not URLs.

  • Controllers listen using @MessagePattern() decorators.


🔹 How It Works

1. Sending a Message

A service sends a message using the NestJS ClientProxy:

// Request–Response (RPC)

client.send({ cmd: 'create_user' }, payload);


// Event (Fire-and-Forget)

client.emit({ cmd: 'user_created' }, payload);


  • send()RPC style (Request–Response)
    The sender expects a reply, similar to calling a function and waiting for a return value.

  • emit()Event style (Fire-and-Forget)
    The sender only notifies that something happened and does not wait for a response.


2. Receiving a Message

A controller in another microservice listens for specific commands:

@MessagePattern({ cmd: 'create_user' })

handleCreateUser(data) {

  // process data and return result

}

Controllers use @MessagePattern() to handle commands, and messages are plain JavaScript objects passed through the broker.


🔹 RabbitMQ Request Layout

  • Pattern / Command – defines the purpose of the message (e.g., { cmd: 'create_user' })

  • Payload (data) – the message body (e.g., { name: 'Camilla', email: 'test@example.com' })

  • Metadata (optional) – correlation IDs, routing keys, timestamps (handled by RabbitMQ)

  • DTOs – ensure type safety and validation


🔹 RabbitMQ Responses

  • Response message – for send() (RPC) requests

  • Acknowledgment (ACK/NACK) – for emit() (event) messages

  • Error message – returned if the service throws or rejects the message


Summary 

  • HTTP Communication is synchronous, uses controllers and decorators, and sends structured JSON with status codes and headers.

  • Message-Based Communication is asynchronous, uses @MessagePattern() for listening, and messages are plain JS objects or DTOs passed through a broker like RabbitMQ.

  • NestJS supports DTOs, exception handling, and metadata management for both communication types.


  |   -- | --