Микросервисы на TypeScript: с чего начать в 2024

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Микросервисы на TypeScript: ваш первый шаг к модульной архитектуре

Представьте, что вы строите дом. Можно возвести одну огромную стену, а затем добавлять к ней комнаты. Но если одна комната сломается — пострадает всё здание. Альтернатива — построить отдельные модули: кухню, спальню, гостиную, каждый со своей проводкой и сантехникой. Примерно так работают микросервисы — независимые, слабо связанные компоненты, которые общаются через сеть.

TypeScript для микросервисов — это не просто модный тренд, а инструмент, который спасает от хаоса. Статическая типизация отлавливает ошибки на этапе компиляции, а не в продакшене. В этой статье мы разберём, с чего начать, если вы хотите перейти от монолита к микросервисам на TypeScript. Без воды, с реальными примерами кода.

Почему TypeScript, а не чистый JavaScript?

Когда вы пишете микросервисы, каждый сервис — это отдельный проект. Без типов легко запутаться: какой формат данных ожидает сервис A, что возвращает сервис B? TypeScript решает эту проблему:

  • Интерфейсы и типы — вы чётко определяете контракты между сервисами.
  • Автокомплит и рефакторинг — IDE подсказывает поля объектов, а переименование не ломает код.
  • Совместимость с Node.js — TypeScript компилируется в JavaScript, работает везде, где есть Node.

Пример: представьте, что сервис заказов отправляет данные сервису доставки. Без типов вы можете случайно передать строку вместо числа. TypeScript скажет: «Эй, тут ожидается number, а ты шлёшь string».

Инструментарий для старта

Чтобы начать, вам понадобятся:

  • Node.js (версия 18+) — среда выполнения.
  • TypeScript — устанавливаем глобально или в проекте.
  • NestJS — фреймворк для серверных приложений. Он из коробки поддерживает микросервисную архитектуру.
  • RabbitMQ или NATS — брокеры сообщений для асинхронного общения.
  • Docker — контейнеризация каждого сервиса.

Не бойтесь, всё это настраивается за 15 минут.

Шаг 1: Создаём первый микросервис с NestJS

NestJS — это как Angular для бэкенда. Он использует декораторы, модули и провайдеры. Установим его:

npm i -g @nestjs/cli
nest new user-service
cd user-service
npm install @nestjs/microservices

Теперь превратим обычное приложение в микросервис. Откроем main.ts:

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.TCP, // или Redis, RabbitMQ
      options: {
        host: '0.0.0.0',
        port: 3001,
      },
    },
  );
  await app.listen();
  console.log('User microservice is listening on port 3001');
}
bootstrap();

Мы создали микросервис, который слушает TCP-порт 3001. Теперь добавим обработчик сообщений в app.controller.ts:

import { Controller } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices';

@Controller()
export class AppController {
  @MessagePattern('get_user')
  getUser(@Payload() data: { id: number }) {
    // Имитация запроса к БД
    return { id: data.id, name: 'Alice', email: 'alice@example.com' };
  }
}

Всё! Первый микросервис готов. Он принимает сообщение с паттерном get_user и возвращает данные пользователя.

Шаг 2: Создаём второй сервис и организуем общение

Сделаем ещё один сервис — order-service. Он будет запрашивать данные у user-service. Создадим его аналогично, но изменим порт на 3002.

В order-service установим клиент для общения:

npm install @nestjs/microservices

Теперь в контроллере заказов напишем вызов к user-service:

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

@Controller('orders')
export class OrdersController {
  private client: ClientProxy;

  constructor() {
    this.client = ClientProxyFactory.create({
      transport: Transport.TCP,
      options: { host: 'localhost', port: 3001 },
    });
  }

  @Get(':id')
  async getOrderWithUser() {
    // Отправляем сообщение и ждём ответ
    const user = await this.client.send('get_user', { id: 1 }).toPromise();
    return { order: 'Book', user };
  }
}

Запустите оба сервиса в разных терминалах. При запросе к http://localhost:3002/orders/1 order-service получит данные от user-service. Магия микросервисов в действии!

Шаг 3: Добавляем RabbitMQ для асинхронности

TCP — хорошо, но если сервис временно недоступен, запрос потеряется. Для надёжности используйте брокеры сообщений. RabbitMQ — популярный выбор.

Установите RabbitMQ через Docker:

docker run -d --name rabbitmq -p 5672:5672 rabbitmq:3-management

Теперь переключим user-service на RabbitMQ. В main.ts меняем транспорт:

const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    transport: Transport.RMQ,
    options: {
      urls: ['amqp://localhost:5672'],
      queue: 'user_queue',
      queueOptions: { durable: false },
    },
  },
);

В order-service обновляем клиент:

this.client = ClientProxyFactory.create({
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'user_queue',
  },
});

Теперь сообщения не теряются: если user-service упадёт, RabbitMQ сохранит их до восстановления.

Шаг 4: Контейнеризация с Docker Compose

Микросервисы должны быть изолированы. Docker Compose поднимает всё одной командой. Создайте docker-compose.yml в корне:

version: '3.8'
services:
  user-service:
    build: ./user-service
    ports:
      - "3001:3001"
    depends_on:
      - rabbitmq

  order-service:
    build: ./order-service
    ports:
      - "3002:3002"
    depends_on:
      - rabbitmq

  rabbitmq:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"
      - "15672:15672"

                
                

Блоги

Рекомендаций по книгам