Ответ
Проект был построен на основе микросервисной архитектуры с четким разделением ответственности.
Стек технологий и компоненты:
| Компонент | Технологии | Назначение |
|---|---|---|
| Frontend | React.js (SPA), TypeScript | Пользовательский интерфейс, общение через REST API. |
| API Gateway | NGINX / Kong | Маршрутизация, SSL-терминация, аутентификация. |
| Бизнес-сервисы | Node.js (Express), Python (Flask) | Основная логика (Auth Service, Order Service, Analytics Service). |
| Базы данных | PostgreSQL (транзакции), MongoDB (документы/аналитика) | Каждый сервис использовал свою схему или БД. |
| Асинхронная коммуникация | RabbitMQ | Обработка фоновых задач (отправка email, генерация отчетов). |
| Оркестрация | Kubernetes (K8s) на AWS (EKS) | Развертывание, масштабирование и управление контейнерами. |
| CI/CD | GitLab CI/CD | Автоматическая сборка Docker-образов, прогон тестов и деплой в K8s. |
| Мониторинг | Prometheus, Grafana, ELK Stack | Сбор метрик, логов и визуализация. |
Пример интеграционного теста для API заказа:
import requests
def test_order_creation():
# 1. Аутентификация
auth_response = requests.post(
"https://api.company.com/auth/login",
json={"username": "test", "password": "secret"}
)
token = auth_response.json()["access_token"]
# 2. Создание заказа
order_response = requests.post(
"https://api.company.com/orders",
json={"product_id": 456, "quantity": 1},
headers={"Authorization": f"Bearer {token}"}
)
# 3. Проверки
assert order_response.status_code == 201
order_data = order_response.json()
assert "id" in order_data
assert order_data["status"] == "PENDING"
# 4. Проверка согласованности (запрос в сервис заказов)
get_response = requests.get(
f"https://api.company.com/orders/{order_data['id']}",
headers={"Authorization": f"Bearer {token}"}
)
assert get_response.status_code == 200
Ключевые принципы: независимое развертывание сервисов, контейнеризация, строгое API-версионирование, автоматизированное тестирование на всех уровнях.
Ответ 18+ 🔞
Так, слушай, а вот представь, блядь, как мы тут проект пилили. Всё по уму, на микросервисах, ёпта! Чтобы один сервис сдох — остальные даже не чихнули, в рот меня чих-пых. Каждый сам за себя, как в диком лесу, только с контейнерами и кубернетисом.
На чём всё это безобразие держалось:
| Что за штука | На чём сделано | Зачем оно надо |
|---|---|---|
| Фронт | React.js, TypeScript | Красивые кнопочки для юзеров, чтобы тыкали. Всё через API болтает. |
| Швейцар (API Gateway) | NGINX / Kong | Встречает гостей, проверяет пропуска (аутентификация), разводит по кабинетам (маршрутизация). |
| Рабочие лошадки (Сервисы) | Node.js (Express), Python (Flask) | Вот тут вся магия: один логины выдает (Auth), другой заказы фасует (Order), третий графики строит (Analytics). |
| Хранилища | PostgreSQL (для строгих транзакций), MongoDB (для всякой аналитической хуйни) | Каждый сервис свою базу юзал, чтобы не мешать друг другу. |
| Почтальоны (Очереди) | RabbitMQ | Чтобы не ждать, пока письмо отправится или отчет сгенерится. Кинул задачу в очередь — и пошёл дальше пить кофе. |
| Надзиратель (Оркестрация) | Kubernetes (K8s) на AWS | Это чтобы наши контейнеры-зэки не разбежались, а чётко работали и масштабировались, когда нагрузка приходит. |
| Конвейер (CI/CD) | GitLab CI/CD | Залил код — оно само соберёт, протестит и выкатит в продакшн. Человек почти не нужен, красота! |
| Смотрящие (Мониторинг) | Prometheus, Grafana, ELK Stack | Чтобы видеть, кто из сервисов сейчас болеет, а кто просто прикидывается. Метрики, логи, графики — всё как у взрослых. |
А вот, смотри, как мы тестировали, чтобы ничего не разъехалось, блядь:
import requests
def test_order_creation():
# 1. Сначала логинимся, получаем токен. Без пропуска не пустят.
auth_response = requests.post(
"https://api.company.com/auth/login",
json={"username": "test", "password": "secret"}
)
token = auth_response.json()["access_token"]
# 2. Пытаемся создать заказ. Это же главное!
order_response = requests.post(
"https://api.company.com/orders",
json={"product_id": 456, "quantity": 1},
headers={"Authorization": f"Bearer {token}"}
)
# 3. Проверяем, что нас не послали и заказ создался.
assert order_response.status_code == 201
order_data = order_response.json()
assert "id" in order_data
assert order_data["status"] == "PENDING"
# 4. А теперь, хитрая жопа, проверяем согласованность: дергаем тот же заказ по айди.
get_response = requests.get(
f"https://api.company.com/orders/{order_data['id']}",
headers={"Authorization": f"Bearer {token}"}
)
assert get_response.status_code == 200
И главные правила, блядь, которые мы выучили кровью: каждый сервис должен уметь деплоиться отдельно от всех, сидеть в своём контейнере, версии API менять аккуратно, а тесты должны гоняться автоматически, иначе — пиздец и ночные дежурства. Вот так-то, ёпта.