# Yobble Gateway (Go)

## О проекте

Это высокопроизводительный API-шлюз, написанный на Go. Он служит единой точкой входа для всех клиентских запросов и направляет их в соответствующие микросервисы.

## Основные возможности

* **Динамическая маршрутизация:** Маршруты определяются в файле `configs/routes.json` и могут быть легко изменены без перезапуска шлюза.
* **Балансировка нагрузки:** Простая балансировка нагрузки (в настоящее время случайный выбор) между несколькими экземплярами сервиса.
* **SSL/TLS Termination:** Шлюз обрабатывает HTTPS-запросы, снимая нагрузку по шифрованию с внутренних сервисов.
* **Фильтрация по GeoIP:** Возможность блокировать запросы из определенных стран.
* **Конфигурация через переменные окружения:** Удобная настройка для различных сред (разработка, продакшн).
* **Логирование:** Структурированное логирование с использованием `slog`.
* **Graceful Shutdown:** Корректное завершение работы приложения, позволяющее завершить обработку текущих запросов.

## Технологический стек

* **Go (Golang)**
* **Gorilla Mux** для маршрутизации
* **maxmind/geoip2-golang** для GeoIP
* **YAML** и **JSON** для конфигурации
* **Docker** для контейнеризации

## Структура проекта

```
.
├── cmd/gateway/main.go      # Точка входа в приложение
├── configs/                   # Файлы конфигурации
│   ├── config.yml             # Основной файл конфигурации
│   └── routes.json            # Файл с маршрутами
├── internal/                  # Внутренняя логика приложения
│   ├── config/                # Работа с конфигурацией
│   ├── logger/                # Логирование
│   ├── middleware/            # Промежуточное ПО (например, для получения Real IP)
│   ├── proxy/                 # Логика проксирования и маршрутизации
│   └── server/                # Настройка и запуск HTTP-сервера
├── pkg/                       # Пакеты, которые могут быть использованы в других проектах
│   └── geoip/                 # Работа с GeoIP
├── geodb/                     # База данных GeoIP
├── SSL/                       # SSL-сертификаты
├── .env.example               # Пример файла с переменными окружения
├── Dockerfile                 # Файл для сборки Docker-образа
└── go.mod                     # Зависимости проекта
```

## Быстрый старт

### 1. Клонирование репозитория

```bash
git clone <URL репозитория>
cd go-yobble-gateway
```

### 2. Конфигурация

Скопируйте файл с примером переменных окружения:

```bash
cp .env.example .env
```

Отредактируйте `.env` и `configs/config.yml` при необходимости.

### 3. Запуск с помощью Docker

Для сборки и запуска приложения в Docker-контейнере выполните:

```bash
docker-compose up --build
```

### 4. Локальный запуск (без Docker)

#### а) Установка зависимостей

```bash
go mod tidy
```

#### б) Запуск приложения

```bash
go run cmd/gateway/main.go --config=configs/config.yml
```

## Конфигурация

### Основная конфигурация (`config.yml`)

* `server`: Настройки хоста и порта сервера.
* `gateway`: Настройки шлюза, включая путь к файлу с маршрутами и базу GeoIP.
* `tls`: Пути к SSL-сертификатам.
* `logging`: Уровень и формат логирования.

### Переменные окружения (`.env`)

Переменные окружения, определенные в `.env`, переопределяют значения по умолчанию в `config.yml`.

### Маршрутизация (`routes.json`)

Файл `routes.json` определяет, как шлюз будет перенаправлять запросы.

**Пример:**

```json
{
  "v1": {
    "/auth": [
      {
        "url": "https://auth-service:5201",
        "role": "master",
        "allow_self_signed": true
      }
    ]
  },
  "default": {
    "/docs": [
      {
        "url": "https://docs-service:5199",
        "role": "slave",
        "allow_self_signed": true
      }
    ]
  }
}
```

* **Ключи верхнего уровня (`v1`, `default`)** - это версии API. Запросы, начинающиеся с `/v1/...`, будут сопоставляться с маршрутами в секции `"v1"`. Если версия не указана, используется секция `"default"`.
* **Ключи второго уровня (`/auth`, `/docs`)** - это префиксы путей. Шлюз ищет наиболее длинное совпадение префикса.
* **`url`** - URL внутреннего сервиса.
* **`allow_self_signed`** - Разрешает использование самоподписанных сертификатов для внутреннего сервиса.

## GeoIP Фильтрация

Шлюз может блокировать доступ для стран, перечисленных в `blocked_countries` в файле `config.yml`. Для работы этой функции необходима база данных `GeoLite2-Country.mmdb` от MaxMind.
