Что такое API Gateway в контексте микросервисной архитектуры

Ответ

API Gateway — это паттерн проектирования и сервер, который выступает как единая точка входа (single entry point) для всех клиентских запросов к бэкенд-сервисам в микросервисной архитектуре.

Вместо того чтобы клиенты напрямую обращались к множеству микросервисов, они отправляют один запрос на API Gateway, который затем маршрутизирует его к нужным сервисам, агрегирует их ответы и возвращает клиенту единый результат.

Ключевые функции:

  • Маршрутизация (Routing): Перенаправляет входящие запросы на соответствующие микросервисы.
  • Агрегация (Aggregation): Собирает данные из нескольких сервисов в один ответ, чтобы уменьшить количество запросов от клиента.
  • Аутентификация и авторизация: Централизованно проверяет права доступа, JWT-токены или API-ключи, снимая эту задачу с каждого микросервиса.
  • Балансировка нагрузки (Load Balancing): Распределяет запросы между несколькими экземплярами одного сервиса.
  • Кэширование: Сохраняет ответы от сервисов для уменьшения времени отклика и нагрузки.
  • Логирование и мониторинг: Является центральной точкой для сбора метрик и логов по всем входящим запросам.

Упрощенный пример агрегации на FastAPI

Этот код эмулирует работу Gateway, который для получения полной информации о заказе обращается к двум разным сервисам (сервису пользователей и сервису заказов).

from fastapi import FastAPI, HTTPException
import httpx # Асинхронная HTTP-библиотека

app = FastAPI(title="API Gateway")

# Адреса внутренних микросервисов
USERS_SERVICE_URL = "http://users-service/api/v1/users"
ORDERS_SERVICE_URL = "http://orders-service/api/v1/orders"

@app.get("/composite/order-details/{order_id}")
async def get_order_details(order_id: int):
    async with httpx.AsyncClient() as client:
        try:
            # 1. Получаем данные о заказе
            order_response = await client.get(f"{ORDERS_SERVICE_URL}/{order_id}")
            order_response.raise_for_status()
            order_data = order_response.json()
            user_id = order_data.get("userId")

            # 2. Получаем данные о пользователе по ID из заказа
            user_response = await client.get(f"{USERS_SERVICE_URL}/{user_id}")
            user_response.raise_for_status()
            user_data = user_response.json()

            # 3. Агрегируем результат
            return {
                "order": order_data,
                "customer": user_data
            }
        except httpx.HTTPStatusError as e:
            raise HTTPException(status_code=e.response.status_code, detail="Error fetching data from a downstream service.")

Популярные готовые решения: AWS API Gateway, Kong, Tyk, NGINX Plus.

Ответ 18+ 🔞

Слушай, а вот этот ваш API Gateway, ну, это ж такая штука, блядь, как будто главный швейцар в ебучем пятизвёздочном отеле для твоих микросервисов, понимаешь?

Вместо того чтобы всяким клиентам-распиздяям бегать по всему отелю и стучаться в каждую дверь — в номер «Пользователи», потом в «Заказы», потом ещё куда-то — они приходят к одному мужику на ресепшн. А этот мужик, ёпта, уже сам знает, к кому и за чем бежать, всё соберёт, и выдаст клиенту один красивый пакетик. И волки сыты, и овцы целы, и микросервисам не надо с каждым идиотом разговаривать.

А делает он, этот швейцар, овердохуища всего:

  • Маршрутизация: Ну, то есть он как навигатор в жопе — запрос пришёл, он сразу понимает, какому сервису его впендюрить.
  • Агрегация: Это вообще магия. Клиенту нужно из трёх сервисов данные — он один запрос делает, а гейтвей сам всё соберёт, как хитрая жопа, и отдаёт готовенькое.
  • Проверка, кто ты такой: Вместо того чтобы каждый сервис сам спрашивал «А твой пропуск где, пидор?», это делает гейтвей один раз. Сэкономил всем кучу нервов.
  • Балансировка: Если сервис «Заказы» в пяти экземплярах бегает, гейтвей будет кидать запросы то одному, то другому, чтобы никто не сдох от нагрузки. Умная жопа.
  • Кэширование: Запомнит ответ, чтобы если тот же дурак придёт с тем же вопросом — не бегать по отелю снова, а сразу из-под стола выдать. Скорость — пиздец!
  • Слежка: Он всё видит, сука! Кто, куда, когда. Все логи и метрики стекаются к нему. Мониторинг, блядь, в одном флаконе.

Вот, смотри, как это примерно выглядит в коде (FastAPI):

Представь, клиенту нужны детали заказа. А они, блядь, размазаны по двум сервисам. Гейтвей сейчас всё разрулит.

from fastapi import FastAPI, HTTPException
import httpx # Асинхронная HTTP-библиотека

app = FastAPI(title="API Gateway")

# Адреса внутренних микросервисов
USERS_SERVICE_URL = "http://users-service/api/v1/users"
ORDERS_SERVICE_URL = "http://orders-service/api/v1/orders"

@app.get("/composite/order-details/{order_id}")
async def get_order_details(order_id: int):
    async with httpx.AsyncClient() as client:
        try:
            # 1. Получаем данные о заказе
            order_response = await client.get(f"{ORDERS_SERVICE_URL}/{order_id}")
            order_response.raise_for_status()
            order_data = order_response.json()
            user_id = order_data.get("userId")

            # 2. Получаем данные о пользователе по ID из заказа
            user_response = await client.get(f"{USERS_SERVICE_URL}/{user_id}")
            user_response.raise_for_status()
            user_data = user_response.json()

            # 3. Агрегируем результат
            return {
                "order": order_data,
                "customer": user_data
            }
        except httpx.HTTPStatusError as e:
            raise HTTPException(status_code=e.response.status_code, detail="Error fetching data from a downstream service.")

Видишь? Клиент дернул один эндпоинт, а гейтвей сам сбегал в два места, всё склеил и отдал. Красота, ёпта!

А если делать всё самому влом — бери готовое: AWS API Gateway, Kong, Tyk. Или NGINX Plus накрутить — тоже вариант, он хоть и старичок, но ещё тот пердун, много чего умеет.