Микросервисы или монолит: что выбрать для вашего проекта в 2026
Каждый второй стартап в Бишкеке, который приходит к нам за разработкой, хочет «микросервисную архитектуру как у Netflix». Иногда эту фразу произносит основатель, у которого ещё нет ни одного пользователя. Иногда - CTO команды из трёх человек, где бэкенд пишет один джуниор.
Мы понимаем откуда это желание. Netflix, Amazon, Uber - компании, ставшие иконами технологического мира, - публично рассказывали о переходе на микросервисы. Конференции, YouTube-доклады, Medium-статьи транслируют одно послание: микросервисы = современно и правильно.
Но вот что обычно остаётся за кадром: Netflix начинал с монолита. Amazon начинал с монолита. Uber начинал с монолита. Все три компании перешли на микросервисы только после того, как их монолиты столкнулись с реальными проблемами масштаба, которые монолитная архитектура уже не могла решить.
Выбор архитектуры - это не вопрос моды и не вопрос «как у больших». Это вопрос денег, скорости разработки и соответствия архитектурного решения реальному масштабу вашего продукта прямо сейчас.
В этой статье - честная позиция Aunimeda, основанная на практике разработки в Кыргызстане: для 95% проектов на нашем рынке монолит (или модульный монолит) - правильный выбор. Разберём почему, и в каких 5% случаев микросервисы действительно оправданы.
Что такое монолит - без страшного названия
Монолит - это приложение, в котором весь код развёртывается как единый процесс. UI-слой, бизнес-логика, доступ к базе данных - всё работает вместе, в одном рантайме.
Это не пренебрежительное слово. WordPress - монолит. Ruby on Rails приложения - монолиты. Django - монолит. Большинство SaaS-продуктов, которые зарабатывают от $1M до $50M ARR, - монолиты. Basecamp, Shopify (до определённого момента), GitHub - все начинали как монолиты и долго оставались ими.
Структура монолита на Node.js / NestJS
src/
├── users/
│ ├── users.module.ts
│ ├── users.controller.ts
│ ├── users.service.ts
│ └── users.repository.ts
├── orders/
│ ├── orders.module.ts
│ ├── orders.controller.ts
│ ├── orders.service.ts
│ └── orders.repository.ts
├── notifications/
│ ├── notifications.module.ts
│ └── notifications.service.ts
├── app.module.ts
└── main.ts
Один процесс. Один деплой. Одна база данных (или несколько схем внутри одной). Все модули общаются напрямую через импорты - никакого HTTP между ними, никакой сетевой задержки.
Реальные преимущества монолита
Простота разработки. Добавить новое поле в сущность - изменяешь один файл. Отладить баг - одна IDE, один стектрейс, один логгер. Дебаггер ставится на одну точку остановки и видит весь стек вызовов.
Единый деплой. Один git push, один пайплайн CI/CD, один сервер (или несколько реплик, но одного и того же образа). Версионирование API не требует координации между десятками сервисов.
Нет сетевых задержек между компонентами. Когда OrdersService вызывает UsersService, это вызов функции в памяти - наносекунды. В микросервисном мире этот же вызов превращается в HTTP-запрос или gRPC-вызов с задержкой в 1–50 мс и вероятностью сетевого сбоя.
Транзакции работают нормально. В монолите с одной базой данных транзакция - это транзакция. В микросервисах, где у каждого сервиса своя БД, транзакция через несколько сервисов требует Saga-паттерна или двухфазного коммита - это десятки страниц дополнительной сложности.
Легко рефакторить. Если вы поняли, что неправильно разбили домены - в монолите это рефакторинг. В микросервисах это согласование API-контрактов между командами, версионирование, потенциально - переезд данных.
Где монолит создаёт реальные проблемы
Масштабирование конкретного компонента. Если у вас API обработки платёжных карт грузит CPU на 90%, а остальные эндпоинты стоят без дела - вы вынуждены масштабировать всё приложение целиком. Горизонтальное масштабирование монолита стоит дороже, чем точечное масштабирование одного микросервиса.
Один крупный баг роняет всё. Утечка памяти в модуле загрузки файлов? Упадёт весь API, включая оформление заказов. В микросервисах сбой одного сервиса изолирован - при правильной реализации circuit breaker.
Когнитивная нагрузка растёт с кодовой базой. Монолит на 500k строк кода изучать сложнее, чем монолит на 50k. Это решаемо дисциплиной и архитектурой, но решение требует усилий.
Что такое микросервисы - без романтики
Микросервисная архитектура - это стиль разработки, при котором приложение разбивается на набор небольших, независимо развёртываемых сервисов. Каждый сервис:
- запускается как отдельный процесс,
- имеет свою базу данных (или свою схему),
- общается с другими сервисами через API (HTTP/REST, gRPC) или очереди сообщений (RabbitMQ, Kafka).
Классическая схема микросервисного маркетплейса:
┌─────────────┐ ┌──────────────┐ ┌──────────────────┐
│ API Gateway│────▶│ User Service│────▶│ Postgres (users)│
└──────┬──────┘ └──────────────┘ └──────────────────┘
│
├───────────▶┌──────────────────┐ ┌──────────────────┐
│ │ Product Service │─▶│Postgres (products│
│ └──────────────────┘ └──────────────────┘
│
├───────────▶┌──────────────────┐ ┌──────────────────┐
│ │ Order Service │─▶│ Postgres (orders)│
│ └──────────────────┘ └──────────────────┘
│
└───────────▶┌──────────────────┐ ┌──────────────────┐
│Notification Svc │─▶│ Redis │
└──────────────────┘ └──────────────────┘
Когда микросервисы дают реальные преимущества
Независимый деплой. Команда, работающая над сервисом уведомлений, деплоит его без согласования с командой платёжного сервиса. Пять деплоев в день вместо одного раз в неделю.
Точечное масштабирование. Сервис поиска по каталогу получает в 100 раз больше запросов, чем сервис управления профилем? Запускаем 50 реплик поиска и 1 реплику профиля. В монолите пришлось бы масштабировать всё.
Технологическая свобода. Сервис обработки видео написан на Python (лучший ML-стек). Сервис транзакций - на Go (высокая конкурентность). API Gateway - на Node.js (удобство разработки). В монолите всё на одном стеке.
Изоляция сбоев. При правильной реализации circuit breaker - падение сервиса рекомендаций не роняет оформление заказов.
Реальные проблемы микросервисов
Distributed systems complexity - это не метафора. Сеть ненадёжна. Сервисы падают. Партиции случаются. Latency непредсказуема. Все эти проблемы, которые в монолите просто не существуют, в микросервисах требуют явного решения: retry-логика, таймауты, circuit breakers, idempotency ключи, компенсирующие транзакции.
Нужна серьёзная DevOps-экспертиза. Kubernetes, service mesh, distributed tracing, centralized logging, health checks, rolling deployments - это отдельная инженерная дисциплина. В монолите системный администратор управляет одним процессом. В микросервисах - оркестрацией десятков.
Latency накапливается. Запрос пользователя на страницу товара может потребовать вызовов к трём сервисам последовательно. 3 × 10 мс = 30 мс только на внутреннюю коммуникацию. При плохой архитектуре этот fan-out вырастает до 200–500 мс.
Тестирование превращается в боль. В монолите интеграционный тест поднимает одно приложение и одну базу. В микросервисах - надо поднять все зависимые сервисы (или замокировать их), что либо медленно, либо ненадёжно.
Архитектурный карго-культ: почему стартапы выбирают микросервисы и почему это ошибка
«Карго-культ» в антропологии - это когда племена копировали внешние атрибуты западной цивилизации (строили взлётные полосы из дерева, надеясь привлечь самолёты с грузом), не понимая реальных причин, почему эти атрибуты работали у других.
Архитектурный карго-культ выглядит так: «Amazon использует микросервисы → Amazon успешен → мы хотим быть успешны → значит нам нужны микросервисы».
Проблема в том, что Amazon перешёл на микросервисы в 2002 году, когда у них было несколько тысяч разработчиков, монолит вырос до такого размера, что изменения в одном разделе регулярно ломали другие, а команды блокировали друг друга на деплоях. Это реальная боль, которую решали микросервисы.
У стартапа с командой из 4 разработчиков эти проблемы просто не существуют.
Что происходит в реальности
Мы наблюдали несколько проектов (не наших клиентов - видели по рынку), которые пошли по пути микросервисов с нуля. Типичный сценарий:
Месяцы 1–2: Команда настраивает инфраструктуру. Docker-образы для каждого сервиса. Kubernetes кластер. API Gateway. Helm charts. CI/CD для каждого репозитория.
Месяц 3: Первая функциональность готова - она работает, но потребовала написать в три раза больше кода, чем ожидалось. Добавить поле к пользовательской сущности означало изменить User Service, обновить контракт API, обновить все сервисы, которые вызывают User Service.
Месяцы 4–5: Баг, который в монолите занял бы час, занимает день - потому что стектрейс обрывается на границе сервиса, и нужно по distributed trace через Jaeger понять, где именно сломалось.
Месяц 6: Инвесторы спрашивают про product-market fit. Команда рассказывает про красивую архитектуру. Продукта почти нет.
Шесть месяцев ушло на инфраструктуру вместо продукта. Это не теоретический риск - это паттерн, который повторяется.
При команде меньше 10 разработчиков микросервисы замедляют скорость разработки в 2–3 раза по сравнению с монолитом. Это не наше мнение - это вывод, который делают инженеры с опытом в обоих подходах.
Когда монолит - правильный выбор
Вот пять критериев, при соблюдении которых монолит будет работать лучше микросервисов:
1. Команда меньше 15 разработчиков. Conway's Law говорит: архитектура системы отражает коммуникационную структуру организации. Микросервисы эффективны, когда разные команды могут работать независимо. Если у вас одна команда - микросервисы создадут накладные расходы без выгоды.
2. Product-market fit ещё не найден. Пока вы не знаете точно, что нужно рынку, требования меняются быстро. В монолите «переехать» пользователей из одного модуля в другой - это рефакторинг. В микросервисах - это согласование контрактов, миграции данных, версионирование API.
3. Нет чёткого разделения бизнес-доменов. Микросервисы требуют чётких границ. Если вы не уверены, где провести границу между «управлением заказом» и «управлением товаром» - проводить её рано. Неправильные границы в микросервисах создают «распределённый монолит» - худшее из двух миров.
4. Бюджет ограничен. Инфраструктура микросервисов стоит денег. Kubernetes кластер в облаке или на VPS - минимум $150–300/мес только на базовую инфраструктуру. Мониторинг, логирование, трейсинг - ещё $50–150/мес. Для стартапа с ограниченным runway это существенно.
5. Нет выделенного DevOps-инженера. Если ваши разработчики сами управляют инфраструктурой - добавление Kubernetes к их задачам уменьшает время на продукт. Для DevOps-задач нужна либо выделенная компетенция, либо зрелая платформа.
Модульный монолит как промежуточное решение
Модульный монолит - это структурированный монолит, в котором модули изолированы с явными интерфейсами, но деплоятся вместе как единый процесс.
Это золотая середина для большинства проектов на нашем рынке. Вот как это выглядит в NestJS:
// users.module.ts - модуль экспортирует только публичные сервисы
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService, UsersRepository],
exports: [UsersService], // только это видно другим модулям
})
export class UsersModule {}
// orders.module.ts - зависит от UsersModule через интерфейс
@Module({
imports: [
TypeOrmModule.forFeature([Order]),
UsersModule, // импортируем модуль, не конкретный репозиторий
],
controllers: [OrdersController],
providers: [OrdersService],
})
export class OrdersModule {}
// orders.service.ts - работает с UsersService через инъекцию зависимостей
@Injectable()
export class OrdersService {
constructor(
private readonly ordersRepository: OrdersRepository,
private readonly usersService: UsersService, // зависимость через интерфейс модуля
) {}
async createOrder(dto: CreateOrderDto): Promise<Order> {
// Прямой вызов в памяти - нет HTTP, нет задержки, нет сетевых ошибок
const user = await this.usersService.findById(dto.userId);
// ...
}
}
Ключевой принцип: модули не знают о внутренней реализации друг друга. OrdersModule не импортирует UsersRepository напрямую - только UsersService. Когда придёт время разбить на микросервисы, вы просто заменяете прямой вызов на HTTP/gRPC клиент - и граница уже проведена правильно.
Когда микросервисы оправданы
Пять ситуаций, в которых микросервисная архитектура реально решает проблему:
1. Кардинально разная нагрузка на компоненты. Если сервис поиска обрабатывает 10 000 запросов/сек, а сервис выставления счётов - 50/сек, их логично масштабировать независимо. Но сначала убедитесь, что у вас реально такие цифры, а не предположения.
2. Разные команды над разными доменами. Когда у вас 30+ разработчиков и три независимые продуктовые команды - микросервисы позволяют им деплоиться независимо, не согласовывая каждый релиз. Conway's Law работает в обе стороны.
3. Принципиально разные требования к надёжности. Сервис обработки платежей требует 99.99% uptime и отдельного аудита безопасности. Сервис отзывов может иметь 99.5%. Разные SLA - разный подход к инфраструктуре.
4. Вы уже выросли из монолита. Монолит стал настолько большим, что изменения в одной части регулярно ломают другие. Деплои занимают 40 минут. Тесты - 2 часа. Команды блокируют друг друга. Это реальная боль, которую решают микросервисы - но это боль роста, не стартового выбора.
5. Есть зрелая DevOps-команда. Kubernetes кластер управляется, мониторинг настроен, distributed tracing работает. Если этого нет - микросервисы создадут больше проблем, чем решат.
Модульный монолит: золотой стандарт 2026
Если вы уходите из этой статьи с одной идеей - пусть это будет она: для большинства проектов в Кыргызстане правильный ответ в 2026 году - модульный монолит на NestJS.
Вот полная структура, которую мы используем в Aunimeda для средних проектов:
src/
├── core/ # Общая инфраструктура
│ ├── database/
│ │ └── database.module.ts
│ ├── auth/
│ │ ├── auth.module.ts
│ │ ├── jwt.strategy.ts
│ │ └── auth.guard.ts
│ └── config/
│ └── config.module.ts
│
├── modules/ # Бизнес-домены
│ ├── users/
│ │ ├── domain/ # Чистая бизнес-логика без зависимостей
│ │ │ ├── user.entity.ts
│ │ │ └── user.service.ts
│ │ ├── infrastructure/ # БД, внешние сервисы
│ │ │ └── user.repository.ts
│ │ └── users.module.ts
│ │
│ ├── products/
│ │ ├── domain/
│ │ ├── infrastructure/
│ │ └── products.module.ts
│ │
│ ├── orders/
│ │ ├── domain/
│ │ ├── infrastructure/
│ │ └── orders.module.ts
│ │
│ └── notifications/
│ ├── domain/
│ ├── infrastructure/
│ └── notifications.module.ts
│
└── app.module.ts
Правило одно: модуль может зависеть только от публичного API другого модуля (то, что тот экспортирует). Никаких прямых импортов из infrastructure/ другого модуля. Это правило насильно соблюдается через структуру exports в NestJS.
Чтобы сделать границы ещё явнее - вводим интерфейсы на уровне домена:
// users/domain/interfaces/user-reader.interface.ts
export interface IUserReader {
findById(id: string): Promise<User | null>;
findByEmail(email: string): Promise<User | null>;
}
// users/users.module.ts - экспортируем через токен интерфейса
@Module({
providers: [
UsersService,
{
provide: 'IUserReader',
useClass: UsersService,
},
],
exports: ['IUserReader'], // другие модули зависят от интерфейса, не от класса
})
export class UsersModule {}
// orders/orders.service.ts - зависит от интерфейса
@Injectable()
export class OrdersService {
constructor(
@Inject('IUserReader') private readonly userReader: IUserReader,
) {}
}
Когда придёт время заменить IUserReader на HTTP-клиент к отдельному User Service - вы просто меняете реализацию за токеном. Все остальные модули не меняются вообще. Вот что значит «готов к микросервисам» - не «написан на микросервисах», а «легко может стать микросервисом».
Когда вы будете готовы выделить, например, notifications в отдельный сервис - вы просто заменяете прямой вызов NotificationsService на публикацию события в очередь (RabbitMQ, Redis Streams). Граница уже прописана - переход займёт дни, а не месяцы.
Этот подход мы рекомендуем всем клиентам, которые заказывают у нас разработку веб-приложений и мобильных приложений с серьёзной бэкенд-частью. Это позволяет начать быстро, сохранить гибкость и не переплачивать за инфраструктуру, которая вам ещё не нужна.
Практический пример: как мы строим маркетплейс в Кыргызстане
Рассмотрим конкретный сценарий: маркетплейс для продавцов в Кыргызстане - каталог, корзина, заказы, уведомления, личный кабинет продавца.
Фаза 1 - Монолит (месяцы 1–6)
Запускаем модульный монолит на NestJS + PostgreSQL. Деплой - один Docker-контейнер на VPS (минимум 4 vCPU / 8 GB RAM). Nginx как reverse proxy.
# docker-compose.yml - простой деплой для начала
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/marketplace
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
db:
image: postgres:16
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=marketplace
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
redis:
image: redis:7-alpine
volumes:
postgres_data:
Весь бэкенд - один процесс. CI/CD - один пайплайн. Мониторинг - один экземпляр Prometheus. Стоимость инфраструктуры: 3 000–5 000 сомов в месяц.
Фаза 2 - Выделяем сервис уведомлений (месяц 6–9)
Первое, что обычно получает высокую нагрузку на маркетплейсе - уведомления. SMS, email, push - всё это синхронно блокировало основной процесс при росте нагрузки.
Выделяем NotificationService в отдельный воркер, который читает из Redis Streams. Основной монолит публикует событие - воркер обрабатывает асинхронно:
// В монолите - публикуем событие
await this.eventEmitter.emit('order.created', {
orderId: order.id,
userId: order.userId,
total: order.total,
});
// Воркер (отдельный процесс) - обрабатывает событие
@OnEvent('order.created')
async handleOrderCreated(event: OrderCreatedEvent) {
await this.smsService.send(event.userId, `Ваш заказ #${event.orderId} принят`);
await this.pushService.send(event.userId, 'Заказ оформлен');
}
На этом этапе у нас уже 2 процесса, но основная кодовая база остаётся монолитом. Стоимость инфраструктуры: 5 000–8 000 сомов/мес.
Фаза 3 - Выделяем поиск (месяц 9–12+)
Когда каталог вырастает до 50 000+ товаров, PostgreSQL LIKE-запросы начинают тормозить. Выделяем Elasticsearch для полнотекстового поиска по каталогу - он работает рядом с монолитом, монолит просто перенаправляет поисковые запросы к нему.
Остальное - управление заказами, кабинет продавца, аналитика - остаётся монолитом ещё очень долго. И это правильно.
Когда действительно нужны полноценные микросервисы
Когда маркетплейс вырастает до 100+ одновременных продавцов, отдельный модуль отчётности начинает грузить БД тяжёлыми аналитическими запросами, которые мешают OLTP-операциям. Вот тогда отчётность выносится в отдельный сервис со своей read-replica базы. Это органический рост, а не выбор архитектуры с нуля.
DevOps для микросервисов: реальная стоимость
Если вы всё-таки пришли к точке, где микросервисы оправданы - нужно понимать, что за этим стоит. Это не страшилка, а честный расчёт.
Минимальный стек для production микросервисов
| Компонент | Что делает | Альтернатива |
|---|---|---|
| Kubernetes | Оркестрация контейнеров | Docker Swarm (проще, для <10 сервисов) |
| Istio / Linkerd | Service mesh (mTLS, traffic management) | Базовые ingress + retry на уровне кода |
| Jaeger / Tempo | Distributed tracing | Без трейсинга работать очень сложно |
| ELK / Loki | Централизованные логи | Loki проще и дешевле ELK |
| Prometheus + Grafana | Мониторинг и алерты | Обязательны |
| API Gateway | Kong, Traefik, или nginx | Nginx достаточно на старте |
| Message broker | RabbitMQ или Kafka | RabbitMQ проще, Kafka для высоких нагрузок |
Ниже - минимальный Kubernetes Deployment для одного микросервиса с правильными health checks, ресурсными лимитами и readiness probe:
# user-service-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
namespace: marketplace
spec:
replicas: 2
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: registry.example.com/user-service:1.4.2
ports:
- containerPort: 3000
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: user-service-secrets
key: database-url
Один такой файл для каждого сервиса, плюс Service + Ingress - и это только базовая конфигурация. Без service mesh, без HorizontalPodAutoscaler, без PodDisruptionBudget. Реальный production setup в 3–5 раз объёмнее. Для большинства команд это огромный операционный груз без соответствующей отдачи.
Стоимость инфраструктуры в сомах (в месяц)
Docker Swarm (малая команда, 5–10 сервисов):
- 3 × VPS по 4 CPU / 8 GB RAM: ~12 000 сом/мес
- Loki + Prometheus + Grafana: включены
- Итого: 12 000–15 000 сом/мес
Kubernetes кластер (средняя компания, 15–30 сервисов):
- Managed Kubernetes (3 node): ~25 000–40 000 сом/мес
- Observability стек (Jaeger, Loki, Grafana): ~5 000–8 000 сом/мес
- Итого: 30 000–50 000 сом/мес
Для сравнения - монолит:
- 1 × VPS 4 CPU / 16 GB RAM + Postgres + Redis: ~4 000–6 000 сом/мес
Разница в инфраструктурных затратах - в 5–8 раз. Для стартапа на ранних стадиях это может означать разницу между 6 месяцами runway и 12.
Если вы готовы к микросервисам и хотите правильно выстроить инфраструктуру - наша команда занимается DevOps и настройкой Kubernetes для production-проектов в Кыргызстане.
FAQ
Можно ли перейти с монолита на микросервисы позже?
Да, и именно так рекомендуется делать. Ключ - это модульный монолит с чёткими границами между доменами. Если вы с самого начала не допускаете прямых зависимостей между модулями и соблюдаете принцип «модуль общается только через свой публичный API», то выделение модуля в отдельный сервис - это работа на 1–2 недели, а не реструктуризация всей архитектуры.
Стратегия Strangler Fig (шаблон Мартина Фаулера) - выделяем части функциональности постепенно, оборачивая старый монолит новыми сервисами, пока он не «задушен» - хорошо работает на практике.
Нужен ли Kubernetes для трёх микросервисов?
Нет. Docker Compose или Docker Swarm отлично справляются с небольшим количеством сервисов (до 10–15). Kubernetes начинает окупать свою сложность при 15+ сервисах или при серьёзных требованиях к автомасштабированию и zero-downtime деплоям.
Kubernetes для трёх сервисов - это как нанять диспетчера для управления тремя таксистами. Диспетчер обходится дороже, чем экономит.
Что лучше для мобильного бэкенда?
Для мобильного приложения (iOS + Android) бэкенд-архитектура решается теми же критериями, что описаны выше. Специфика мобильного бэкенда - это REST или GraphQL API, push-уведомления, refresh token логика, offline-синхронизация.
Модульный монолит на NestJS с единым REST API отлично работает как бэкенд для мобильных приложений - даже при десятках тысяч активных пользователей, если сервер правильно настроен. Микросервисы для мобильного бэкенда нужны в тех же случаях, что и для веб - при реальных проблемах масштаба.
Как тестировать микросервисы?
Тестирование - одна из самых болезненных тем в микросервисной архитектуре. Практически правильный подход:
- Unit-тесты каждого сервиса изолированно (моки для всех зависимостей) - быстро, надёжно.
- Contract testing через Pact или аналоги - каждый сервис проверяет, что его API-контракт с другими сервисами соблюдается.
- Integration-тесты с реальными зависимостями - поднимаются через Docker Compose в CI, медленно, но необходимы.
- E2E-тесты только для критических пользовательских флоу - дорогие в поддержке, держать минимум.
В монолите достаточно unit + integration тестов. В микросервисах добавляется весь слой contract testing - это дополнительные инвестиции.
GraphQL vs REST для микросервисов?
REST с чёткими эндпоинтами - стандартный выбор для коммуникации между сервисами. gRPC - быстрее и строже (Protobuf контракты), хороший выбор для высоконагруженных внутренних вызовов.
GraphQL оправдан на уровне API Gateway (один GraphQL endpoint, который агрегирует данные из нескольких сервисов) - это паттерн называется Federation (реализован в Apollo Federation). Но GraphQL для прямой коммуникации между сервисами добавляет unnecessary complexity без значимых преимуществ.
Подведём черту - и что дальше
Выбор архитектуры - это инженерное решение, которое должно соответствовать реальному контексту: размеру команды, стадии продукта, бюджету на инфраструктуру.
Если вы стартап или компания среднего размера в Кыргызстане:
- Начинайте с модульного монолита. Быстро, дёшево, управляемо.
- Соблюдайте модульные границы с первого дня. Это ваша страховка на будущее.
- Выделяйте компоненты в отдельные сервисы только при реальной боли - не из-за того, что так делает Netflix.
- Инвестируйте в продукт, а не в инфраструктуру, пока не достигнете product-market fit.
Если вы уже выросли из монолита или изначально строите платформу с несколькими независимыми командами - микросервисы разумны. Но тогда вам нужна зрелая DevOps-практика.
Планируете новый проект и хотите получить честную архитектурную рекомендацию под ваш конкретный случай?
- Веб-приложение или бэкенд API → Разработка веб-сайтов и приложений
- Бэкенд для мобильного приложения → Разработка мобильных приложений
- Настройка DevOps, Kubernetes, CI/CD → DevOps услуги
- Обсудить архитектуру вашего проекта → Написать нам
Мы не продаём архитектуру ради архитектуры. Мы строим системы, которые работают при вашем текущем масштабе и растут вместе с вашим бизнесом.