Microservices — HTTP orqali ma'lumot almashish
Muammodan boshlaylik
Oldingi darsda RabbitMQ bilan servislar orasida xabar almashishni ko'rdik. Lekin har doim message broker kerak emas.
Ba'zida eng oddiy yondashuv yaxshi: Orders Service inventarni tekshirish uchun Inventory Service ga oddiy HTTP so'rov yuboradi.
Qachon HTTP, qachon RabbitMQ?
HTTP: RabbitMQ:
────────────────── ──────────────────
Javob darhol kerak Fon vazifalar
Oddiy so'rov-javob Reliability muhim
Kichik loyiha Ko'p servis, yuqori yuk
Kichik loyihalarda HTTP yetarli va sodda. Yirik tizimda message queue kerak.
O'rnatish
npm install @nestjs/axios axios
Fayl tuzilmasi
src/
orders/
orders.module.ts ← HttpModule import qilinadi
orders.service.ts ← HTTP so'rov shu yerdan yuboriladi
HttpModule ulash
// orders/orders.module.ts
import { Module } from '@nestjs/common';
import { HttpModule } from '@nestjs/axios';
import { OrdersService } from './orders.service';
@Module({
imports: [HttpModule], // ← shu yerga qo'shildi
providers: [OrdersService],
})
export class OrdersModule {}
Boshqa servisce so'rov yuborish
// orders/orders.service.ts
import { Injectable, BadRequestException } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
@Injectable()
export class OrdersService {
constructor(private httpService: HttpService) {}
async createOrder(dto: { productId: number; quantity: number; email: string }) {
// Inventory Service dan stok tekshirish
const response = await firstValueFrom(
this.httpService.get(`http://inventory-service:3001/stock/${dto.productId}`)
);
if (response.data.quantity < dto.quantity) {
throw new BadRequestException('Mahsulot yetarli emas');
}
return { id: Date.now(), ...dto };
}
}
Nima uchun firstValueFrom()?
HttpService ichida Axios ishlatadi, lekin javobni RxJS Observable sifatida qaytaradi. firstValueFrom() uni oddiy Promise ga aylantiradi — await bilan ishlash uchun.
// Observable → Promise
const response = await firstValueFrom(this.httpService.get(url));
// response.data — asosiy ma'lumot
console.log(response.data);
URL larni .env da saqlash
URL ni kod ichiga qattiq yozmaslik kerak — servis manzili o'zgarishi mumkin:
# .env
INVENTORY_SERVICE_URL=http://inventory-service:3001
// orders/orders.service.ts
import { ConfigService } from '@nestjs/config';
@Injectable()
export class OrdersService {
constructor(
private httpService: HttpService,
private config: ConfigService,
) {}
async getStock(productId: number) {
const baseUrl = this.config.get('INVENTORY_SERVICE_URL');
const response = await firstValueFrom(
this.httpService.get(`${baseUrl}/stock/${productId}`)
);
return response.data;
}
}
Xatolarni boshqarish
Boshqa servis mavjud bo'lmasa yoki xato qaytarsa:
async getStock(productId: number) {
try {
const response = await firstValueFrom(
this.httpService.get(`${this.baseUrl}/stock/${productId}`)
);
return response.data;
} catch (error) {
if (error.response?.status === 404) {
throw new NotFoundException('Mahsulot topilmadi');
}
throw new ServiceUnavailableException('Inventory service ishlamayapti');
}
}
Docker Compose da servis nomi
Docker Compose da servislar bir-birini nomi bilan topadi — IP manzil kerak emas:
# docker-compose.yml
services:
orders-service:
build: ./orders
environment:
INVENTORY_SERVICE_URL: http://inventory-service:3001
inventory-service:
build: ./inventory
ports:
- "3001:3001"
inventory-service nomi Docker ichki DNS orqali avtomatik IP manzilga aylanadi.
Tez-tez uchraydigan xatolar
1. ECONNREFUSED
connect ECONNREFUSED inventory-service:3001
Sababi: Servis ishlamayapti yoki nomi noto'g'ri.
Yechim: docker compose logs inventory-service bilan xatoni ko'ring.
2. Timeout
Sababi: Servis javob bermayapti yoki juda sekin.
Yechim: HttpModule.register({ timeout: 5000 }) bilan vaqt chegarasi qo'ying.
Xulosa
HttpService— boshqa servisce HTTP so'rov yuborish uchunfirstValueFrom()— Observable ni Promise ga aylantiradi- URL larni
.envda saqlang, kod ichiga yozmang - Docker Compose da servislar nomi orqali bir-birini topadi
- Xatolarni
try/catchbilan boshqaring
**Keyingi dars: 42-dars: Bull Queue — task queue, background jobs**