Sobes.tech
Senior
37

Mikroservisų architektūros projektavimo užduotis: kaip teikti duomenis užsakymų lentelei (produktai, kainos, užsakymai), kai yra trys atskiri mikroservisai?

Įmonės kur klausė
ИП Ганус Александр Андреевич

Atsakymas iš AI

sobes.tech AI

Для предоставления данных для таблицы заказов, когда есть три отдельных микросервиса (товары, цены, заказы), обычно используют один из следующих подходов:

  1. API Gateway / Aggregator Service Создаётся отдельный сервис, который обращается к трём микросервисам, агрегирует данные и возвращает фронтенду уже объединённый результат. Это снижает количество запросов с клиента и инкапсулирует логику агрегации.

  2. Backend for Frontend (BFF) Специализированный backend, оптимизированный под нужды конкретного фронтенда, который собирает данные из разных микросервисов и формирует удобный для отображения формат.

  3. Event-driven / CQRS с проекциями Использование событийной архитектуры, где отдельный сервис поддерживает проекцию (read model), объединяющую данные из трёх сервисов в единую структуру, обновляемую в режиме реального времени.

Пример API Gateway на Python (FastAPI):

from fastapi import FastAPI
import httpx

app = FastAPI()

@app.get('/orders_table')
async def get_orders_table():
    async with httpx.AsyncClient() as client:
        orders = await client.get('http://orders-service/orders')
        products = await client.get('http://products-service/products')
        prices = await client.get('http://prices-service/prices')

    # Пример простого объединения данных
    orders_data = orders.json()
    products_data = {p['id']: p for p in products.json()}
    prices_data = {pr['product_id']: pr['price'] for pr in prices.json()}

    result = []
    for order in orders_data:
        product = products_data.get(order['product_id'], {})
        price = prices_data.get(order['product_id'], None)
        result.append({
            'order_id': order['id'],
            'product_name': product.get('name'),
            'price': price,
            'quantity': order['quantity']
        })
    return result

Такой подход позволяет фронтенду получить все необходимые данные одним запросом.