Skip to content

About

Timofei Ermakov, NoSQL class, 1st year PiRSBD Master ITMO

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

EventHub

CI Go Docker

Backend-сервис платформы мероприятий для практического изучения NoSQL баз данных. Пользователи регистрируются, создают события, оставляют реакции и отзывы, а система строит рекомендации на основе графа предпочтений.

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

Категория Технология
Язык Go 1.25
Сборка и запуск Docker, Docker Compose, Makefile
Документация API Swagger (swaggo), Postman Collection
MongoDB go.mongodb.org/mongo-driver — пользователи и события (sharded cluster)
Cassandra github.com/gocql/gocql — реакции и отзывы
Neo4j github.com/neo4j/neo4j-go-driver/v5 — граф рекомендаций
Redis github.com/redis/go-redis/v9 — сессии и кэши

Архитектура проекта

Структура каталогов

Путь Назначение
cmd/app/ Точка входа, инициализация зависимостей и HTTP-роутов
internal/handler/ HTTP-слой: парсинг запросов, cookie-сессии, коды ответов
internal/service/ Бизнес-логика и orchestration между хранилищами
internal/repository/ Доступ к MongoDB, Cassandra, Neo4j, Redis
internal/model/ Доменные модели (User, Event, Review, Reaction)
internal/session/ Хранение сессий в Redis
internal/config/ Загрузка конфигурации из env
api/ Postman-коллекция и YAML-описания запросов
docs/ Swagger-артефакты (swagger.yaml, swagger.json)

Схема взаимодействия компонентов

flowchart TD
  Client[ClientOrPostman] --> Handlers[HttpHandlers]
  Handlers --> Services[BusinessServices]
  Services --> Mongo[(MongoDB)]
  Services --> Cassandra[(Cassandra)]
  Services --> Neo4j[(Neo4j)]
  Services --> Redis[(Redis)]
Loading

Основные сущности и связи

erDiagram
  User ||--o{ Event : creates
  User ||--o{ EventReaction : makes
  User ||--o{ EventReview : writes
  Event ||--o{ EventReaction : has
  Event ||--o{ EventReview : has
  User ||--o{ LIKED : graph_edge
  Event ||--o{ LIKED : graph_edge
Loading

Распределение данных по NoSQL

Хранилище Сущности Назначение
MongoDB users, events Основные документы, фильтрация и индексы
Cassandra event_reactions, event_reviews Высокочастотные записи реакций и отзывов
Neo4j узлы User, Event, ребро LIKED Коллаборативные рекомендации
Redis сессии, кэши реакций/отзывов/рекомендаций Быстрый доступ и TTL-кэширование

Поток запроса: Client → Handler → Service → Repository → NoSQL → ответ.

Функциональные требования / Use Cases

  1. Регистрация и аутентификация — пользователь регистрируется (POST /users) или входит (POST /auth/login); сессия хранится в cookie X-Session-Id (Redis).
  2. Анонимная сессия — POST /session создаёт или продлевает сессию без привязки к пользователю.
  3. Создание и поиск событий — авторизованный пользователь создаёт событие; список поддерживает фильтры по title, category, price, city, дате, организатору.
  4. Редактирование события — организатор обновляет category, price, city через PATCH /events/{id}.
  5. Реакции — like/dislike сохраняются в Cassandra; агрегаты по title кэшируются в Redis.
  6. Отзывы — create/list/patch в Cassandra; один отзыв на пользователя на событие; агрегаты рейтинга кэшируются в Redis.
  7. Рекомендации — GET /recommendations использует Neo4j-граф и cache-aside в Redis.
  8. Мониторинг — GET /health и Swagger UI на /swagger/.

API

Аутентификация — cookie X-Session-Id. Рекомендуемый порядок вызовов в Postman:

  1. Session → Create or Refresh Session
  2. Users → Register User или Auth → Login
  3. Events → Create Event → реакции / отзывы / рекомендации

Примеры запросов и ответов

Healthcheck

GET /health
{"status":"ok"}

Регистрация пользователя

POST /users
Content-Type: application/json

{
  "full_name": "Demo User",
  "username": "demo.user",
  "password": "demo-password"
}

Ответ: 201 Created (тело пустое, в Set-Cookie — X-Session-Id).

Создание события

POST /events
Content-Type: application/json
Cookie: X-Session-Id=<session_id>

{
  "title": "NDBX Meetup",
  "address": "Nevsky Prospect 1",
  "started_at": "2026-06-01T18:00:00Z",
  "finished_at": "2026-06-01T20:00:00Z",
  "description": "Community meetup"
}
{"id": "665f1a2b3c4d5e6f7a8b9c0d"}

Список событий с агрегатами

GET /events?include=reactions,reviews&limit=10&offset=0
{
  "events": [
    {
      "id": "665f1a2b3c4d5e6f7a8b9c0d",
      "title": "NDBX Meetup",
      "category": "meetup",
      "price": 500,
      "description": "Community meetup",
      "location": {"address": "Nevsky Prospect 1", "city": "Saint Petersburg"},
      "created_at": "2026-05-01T12:00:00Z",
      "created_by": "665f0a1b2c3d4e5f6a7b8c9d",
      "started_at": "2026-06-01T18:00:00Z",
      "finished_at": "2026-06-01T20:00:00Z",
      "reactions": {"likes": 3, "dislikes": 1},
      "reviews": {"count": 2, "rating": 4.5}
    }
  ],
  "count": 1
}

Рекомендации

GET /recommendations
Cookie: X-Session-Id=<session_id>
{
  "events": [
    {
      "id": "665f2b3c4d5e6f7a8b9c0d1e",
      "title": "Go Conference",
      "category": "meetup",
      "price": 0,
      "location": {"address": "ITMO University"},
      "started_at": "2026-07-15T10:00:00Z",
      "finished_at": "2026-07-15T18:00:00Z"
    }
  ]
}

Маршруты

Метод Путь Описание
GET /health Проверка доступности
GET /swagger/ Swagger UI
POST /session Создать/обновить сессию
POST /users Регистрация
GET /users Список пользователей
GET /users/{id} Пользователь по ID
GET /users/{id}/events События пользователя
POST /auth/login Вход
POST /auth/logout Выход
POST /events Создать событие
GET /events Список событий
GET /events/{id} Событие по ID
PATCH /events/{id} Обновить событие
GET /recommendations Рекомендации
POST /events/{id}/like Лайк
POST /events/{id}/dislike Дизлайк
POST /events/{id}/reviews Создать отзыв
GET /events/{id}/reviews Список отзывов
PATCH /events/{id}/reviews/{review_id} Обновить отзыв

Инструкция по запуску

Требования

  • Docker и Docker Compose
  • Make (GNU Make)
  • Go 1.25+ (для локального запуска тестов)

Пошаговый запуск

  1. Клонируйте репозиторий и перейдите в корень проекта.
  2. Проверьте файл .env.local — порты, учётные данные БД, TTL кэшей.
  3. Запустите окружение:
make run
  1. Проверьте статус контейнеров:
make services
  1. Убедитесь, что API отвечает:
curl http://localhost:8080/health
  1. Откройте Swagger: http://localhost:8080/swagger/ или импортируйте api/eventhub.postman_collection.json в Postman.

Остановка

make stop    # остановить контейнеры
make clean   # остановить и удалить тома (полная очистка данных)

Для отладки в foreground: make rund.

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

Переменные окружения задаются в .env.local и читаются приложением через internal/config/config.go.

Приложение

Переменная Описание Значение по умолчанию
APP_HOST Хост HTTP-сервера 0.0.0.0
APP_PORT Порт HTTP-сервера 8080
APP_USER_SESSION_TTL TTL сессии пользователя (сек) 60
APP_LIKE_TTL TTL кэша реакций (сек) 60
APP_EVENT_REVIEWS_TTL TTL кэша отзывов (сек) 120
APP_RECOMMENDATIONS_TTL TTL кэша рекомендаций (сек) 60

Redis

Переменная Описание Значение по умолчанию
REDIS_HOST Хост Redis redis
REDIS_PORT Порт Redis 6379
REDIS_PASSWORD Пароль Redis (пусто)
REDIS_DB Номер БД Redis 0

MongoDB

Переменная Описание Значение по умолчанию
MONGODB_HOST Хост mongos mongos
MONGODB_PORT Порт mongos 27017
MONGODB_DATABASE Имя базы eventhub
MONGODB_USER Пользователь eventhub
MONGODB_PASSWORD Пароль eventhub
MONGODB_INIT_SLEEP_SECONDS Задержка инициализации кластера 10
MONGODB_CONFIG_REPLICA_SET Имя config replica set cfg-rs
MONGODB_CONFIG1_PORT Порт config node 1 27111
MONGODB_CONFIG2_PORT Порт config node 2 27112
MONGODB_CONFIG3_PORT Порт config node 3 27113
MONGODB_SHARD1_NAME Имя shard 1 shard1
MONGODB_SHARD1_REPLICA_SET Replica set shard 1 shard1-rs
MONGODB_SHARD1_NODE1_PORT Порт shard1 node 1 27211
MONGODB_SHARD1_NODE2_PORT Порт shard1 node 2 27212
MONGODB_SHARD1_NODE3_PORT Порт shard1 node 3 27213
MONGODB_SHARD2_NAME Имя shard 2 shard2
MONGODB_SHARD2_REPLICA_SET Replica set shard 2 shard2-rs
MONGODB_SHARD2_NODE1_PORT Порт shard2 node 1 27311
MONGODB_SHARD2_NODE2_PORT Порт shard2 node 2 27312
MONGODB_SHARD2_NODE3_PORT Порт shard2 node 3 27313

Cassandra

Переменная Описание Значение по умолчанию
CASSANDRA_HOSTS Хосты (через запятую) cassandra
CASSANDRA_PORT Порт CQL 9042
CASSANDRA_USERNAME Имя пользователя (пусто)
CASSANDRA_PASSWORD Пароль (пусто)
CASSANDRA_KEYSPACE Keyspace testkeyspace
CASSANDRA_CONSISTENCY Уровень консистентности ONE
CASSANDRA_CLUSTER_NAME Имя кластера EventHubCluster
CASSANDRA_DC Datacenter dc1
CASSANDRA_RACK Rack rack1
CASSANDRA_MAX_HEAP_SIZE Max heap 512M
CASSANDRA_HEAP_NEWSIZE New gen heap 128M
CASSANDRA_MEM_LIMIT Лимит памяти контейнера 1g
CASSANDRA_MEM_RESERVATION Резерв памяти 512m

Neo4j

Переменная Описание Значение по умолчанию
NEO4J_URL Bolt URL bolt://neo4j:7687
NEO4J_USERNAME Имя пользователя neo4j
NEO4J_PASSWORD Пароль password
NEO4J_BOLT_PORT Bolt-порт 7687
NEO4J_HTTP_PORT HTTP-порт браузера 7474

Тестирование

Unit-тесты

go test ./...

Покрыты сервисы с mock-репозиториями:

Интеграционные и автоматизированные end-to-end тесты в репозитории не реализованы; проверка API выполняется через Postman-коллекцию и CI autograder (.github/workflows/eventhub.yml).

API smoke-тест

  1. make run
  2. Импортировать api/eventhub.postman_collection.json
  3. Выполнить запросы по порядку: Session → Register/Login → Events

P.S.

Каждая СУБД решает свою задачу: MongoDB — документы, Cassandra — write-heavy реакции/отзывы, Neo4j — граф рекомендаций, Redis — сессии и кэш.

Сессия передаётся через HttpOnly cookie X-Session-Id. В Postman переменная {{session_id}} заполняется автоматически test-скриптами.

TLDR: запуск через make run, долго стартует - поднимается sharded MongoDB cluster, Cassandra, Neo4j и init-скрипты. Дождитесь healthy у всех сервисов (make services).

Swagger: после запуска — http://localhost:8080/swagger/. Спецификация генерируется swaggo в docs/swagger.yaml.

Как сбросить все данные? drop database :) make clean удалит тома Docker и очистит состояние всех БД.

About

Timofei Ermakov, NoSQL class, 1st year PiRSBD Master ITMO

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages